1/*	$NetBSD: t_bpfjit.c,v 1.2 2014/07/08 21:44:26 alnsn Exp $ */
2
3/*-
4 * Copyright (c) 2011-2012, 2014 Alexander Nasonov.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
17 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__RCSID("$NetBSD: t_bpfjit.c,v 1.2 2014/07/08 21:44:26 alnsn Exp $");
31
32#include <sys/param.h>
33#include <sys/mbuf.h>
34#include <unistd.h>
35
36#include <net/bpf.h>
37#include <net/bpfjit.h>
38
39#include <stdint.h>
40#include <string.h>
41
42#include <rump/rump.h>
43#include <rump/rump_syscalls.h>
44
45#include "../../net/bpf/h_bpf.h"
46
47/* XXX: atf-c.h has collisions with mbuf */
48#undef m_type
49#undef m_data
50#include <atf-c.h>
51
52#include "../../h_macros.h"
53
54
55static uint8_t deadbeef_at_5[16] = {
56	0, 0xf1, 2, 0xf3, 4, 0xde, 0xad, 0xbe, 0xef, 0xff
57};
58
59static inline
60unsigned int jitcall(bpfjit_func_t fn,
61    const uint8_t *pkt, unsigned int wirelen, unsigned int buflen)
62{
63	bpf_args_t args;
64
65	args.pkt = pkt;
66	args.wirelen = wirelen;
67	args.buflen = buflen;
68
69	return fn(NULL, &args);
70}
71
72ATF_TC(bpfjit_empty);
73ATF_TC_HEAD(bpfjit_empty, tc)
74{
75	atf_tc_set_md_var(tc, "descr",
76	    "Test that JIT compilation of an empty bpf program fails");
77}
78
79ATF_TC_BODY(bpfjit_empty, tc)
80{
81	struct bpf_insn dummy;
82	bpfjit_func_t fn;
83
84	RZ(rump_init());
85
86	rump_schedule();
87	fn = rumpns_bpfjit_generate_code(NULL, &dummy, 0);
88	rump_unschedule();
89
90	ATF_CHECK(fn == NULL);
91}
92
93ATF_TC(bpfjit_alu_add_k);
94ATF_TC_HEAD(bpfjit_alu_add_k, tc)
95{
96	atf_tc_set_md_var(tc, "descr",
97	    "Test JIT compilation of BPF_ALU+BPF_ADD+BPF_K");
98}
99
100ATF_TC_BODY(bpfjit_alu_add_k, tc)
101{
102	static struct bpf_insn insns[] = {
103		BPF_STMT(BPF_LD+BPF_IMM, 3),
104		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 2),
105		BPF_STMT(BPF_RET+BPF_A, 0)
106	};
107
108	uint8_t pkt[1]; /* the program doesn't read any data */
109
110	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
111
112	RZ(rump_init());
113
114	ATF_CHECK(prog_validate(insns, insn_count));
115	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 5);
116}
117
118ATF_TC(bpfjit_alu_sub_k);
119ATF_TC_HEAD(bpfjit_alu_sub_k, tc)
120{
121	atf_tc_set_md_var(tc, "descr",
122	    "Test JIT compilation of BPF_ALU+BPF_SUB+BPF_K");
123}
124
125ATF_TC_BODY(bpfjit_alu_sub_k, tc)
126{
127	static struct bpf_insn insns[] = {
128		BPF_STMT(BPF_LD+BPF_IMM, 1),
129		BPF_STMT(BPF_ALU+BPF_SUB+BPF_K, 2),
130		BPF_STMT(BPF_RET+BPF_A, 0)
131	};
132
133	uint8_t pkt[1]; /* the program doesn't read any data */
134
135	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
136
137	RZ(rump_init());
138
139	ATF_CHECK(prog_validate(insns, insn_count));
140	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX);
141}
142
143ATF_TC(bpfjit_alu_mul_k);
144ATF_TC_HEAD(bpfjit_alu_mul_k, tc)
145{
146	atf_tc_set_md_var(tc, "descr",
147	    "Test JIT compilation of BPF_ALU+BPF_MUL+BPF_K");
148}
149
150ATF_TC_BODY(bpfjit_alu_mul_k, tc)
151{
152	static struct bpf_insn insns[] = {
153		BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)),
154		BPF_STMT(BPF_ALU+BPF_MUL+BPF_K, 3),
155		BPF_STMT(BPF_RET+BPF_A, 0)
156	};
157
158	uint8_t pkt[1]; /* the program doesn't read any data */
159
160	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
161
162	RZ(rump_init());
163
164	ATF_CHECK(prog_validate(insns, insn_count));
165	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xfffffffd);
166}
167
168ATF_TC(bpfjit_alu_div0_k);
169ATF_TC_HEAD(bpfjit_alu_div0_k, tc)
170{
171	atf_tc_set_md_var(tc, "descr",
172	    "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=0");
173}
174
175ATF_TC_BODY(bpfjit_alu_div0_k, tc)
176{
177	static struct bpf_insn insns[] = {
178		BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 0),
179		BPF_STMT(BPF_RET+BPF_A, 0)
180	};
181
182	uint8_t pkt[1]; /* the program doesn't read any data */
183
184	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
185
186	RZ(rump_init());
187
188	//ATF_CHECK(prog_validate(insns, insn_count));
189	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0);
190}
191
192ATF_TC(bpfjit_alu_div1_k);
193ATF_TC_HEAD(bpfjit_alu_div1_k, tc)
194{
195	atf_tc_set_md_var(tc, "descr",
196	    "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=1");
197}
198
199ATF_TC_BODY(bpfjit_alu_div1_k, tc)
200{
201	static struct bpf_insn insns[] = {
202		BPF_STMT(BPF_LD+BPF_IMM, 7),
203		BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 1),
204		BPF_STMT(BPF_RET+BPF_A, 0)
205	};
206
207	uint8_t pkt[1]; /* the program doesn't read any data */
208
209	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
210
211	RZ(rump_init());
212
213	ATF_CHECK(prog_validate(insns, insn_count));
214	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 7);
215}
216
217ATF_TC(bpfjit_alu_div2_k);
218ATF_TC_HEAD(bpfjit_alu_div2_k, tc)
219{
220	atf_tc_set_md_var(tc, "descr",
221	    "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=2");
222}
223
224ATF_TC_BODY(bpfjit_alu_div2_k, tc)
225{
226	static struct bpf_insn insns[] = {
227		BPF_STMT(BPF_LD+BPF_IMM, 7),
228		BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 2),
229		BPF_STMT(BPF_RET+BPF_A, 0)
230	};
231
232	uint8_t pkt[1]; /* the program doesn't read any data */
233
234	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
235
236	RZ(rump_init());
237
238	ATF_CHECK(prog_validate(insns, insn_count));
239	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 3);
240}
241
242ATF_TC(bpfjit_alu_div4_k);
243ATF_TC_HEAD(bpfjit_alu_div4_k, tc)
244{
245	atf_tc_set_md_var(tc, "descr",
246	    "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=4");
247}
248
249ATF_TC_BODY(bpfjit_alu_div4_k, tc)
250{
251	static struct bpf_insn insns[] = {
252		BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)),
253		BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4),
254		BPF_STMT(BPF_RET+BPF_A, 0)
255	};
256
257	uint8_t pkt[1]; /* the program doesn't read any data */
258
259	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
260
261	RZ(rump_init());
262
263	ATF_CHECK(prog_validate(insns, insn_count));
264	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0x3fffffff);
265}
266
267ATF_TC(bpfjit_alu_div10_k);
268ATF_TC_HEAD(bpfjit_alu_div10_k, tc)
269{
270	atf_tc_set_md_var(tc, "descr",
271	    "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=10");
272}
273
274ATF_TC_BODY(bpfjit_alu_div10_k, tc)
275{
276	static struct bpf_insn insns[] = {
277		BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)),
278		BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 10),
279		BPF_STMT(BPF_RET+BPF_A, 0)
280	};
281
282	uint8_t pkt[1]; /* the program doesn't read any data */
283
284	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
285
286	RZ(rump_init());
287
288	ATF_CHECK(prog_validate(insns, insn_count));
289	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 429484384);
290}
291
292ATF_TC(bpfjit_alu_div10000_k);
293ATF_TC_HEAD(bpfjit_alu_div10000_k, tc)
294{
295	atf_tc_set_md_var(tc, "descr",
296	    "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=10000");
297}
298
299ATF_TC_BODY(bpfjit_alu_div10000_k, tc)
300{
301	static struct bpf_insn insns[] = {
302		BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)),
303		BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 10000),
304		BPF_STMT(BPF_RET+BPF_A, 0)
305	};
306
307	uint8_t pkt[1]; /* the program doesn't read any data */
308
309	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
310
311	RZ(rump_init());
312
313	ATF_CHECK(prog_validate(insns, insn_count));
314	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 429484);
315}
316
317ATF_TC(bpfjit_alu_div7609801_k);
318ATF_TC_HEAD(bpfjit_alu_div7609801_k, tc)
319{
320	atf_tc_set_md_var(tc, "descr",
321	    "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=7609801");
322}
323
324ATF_TC_BODY(bpfjit_alu_div7609801_k, tc)
325{
326	static struct bpf_insn insns[] = {
327		BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294967295)),
328		BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, UINT32_C(7609801)),
329		BPF_STMT(BPF_RET+BPF_A, 0)
330	};
331
332	uint8_t pkt[1]; /* the program doesn't read any data */
333
334	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
335
336	RZ(rump_init());
337
338	ATF_CHECK(prog_validate(insns, insn_count));
339	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 564);
340}
341
342ATF_TC(bpfjit_alu_div80000000_k);
343ATF_TC_HEAD(bpfjit_alu_div80000000_k, tc)
344{
345	atf_tc_set_md_var(tc, "descr",
346	    "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=0x80000000");
347}
348
349ATF_TC_BODY(bpfjit_alu_div80000000_k, tc)
350{
351	static struct bpf_insn insns[] = {
352		BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffde)),
353		BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, UINT32_C(0x80000000)),
354		BPF_STMT(BPF_RET+BPF_A, 0)
355	};
356
357	uint8_t pkt[1]; /* the program doesn't read any data */
358
359	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
360
361	RZ(rump_init());
362
363	ATF_CHECK(prog_validate(insns, insn_count));
364	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 1);
365}
366
367ATF_TC(bpfjit_alu_and_k);
368ATF_TC_HEAD(bpfjit_alu_and_k, tc)
369{
370	atf_tc_set_md_var(tc, "descr",
371	    "Test JIT compilation of BPF_ALU+BPF_AND+BPF_K");
372}
373
374ATF_TC_BODY(bpfjit_alu_and_k, tc)
375{
376	static struct bpf_insn insns[] = {
377		BPF_STMT(BPF_LD+BPF_IMM, 0xdead),
378		BPF_STMT(BPF_ALU+BPF_AND+BPF_K, 0xbeef),
379		BPF_STMT(BPF_RET+BPF_A, 0)
380	};
381
382	uint8_t pkt[1]; /* the program doesn't read any data */
383
384	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
385
386	RZ(rump_init());
387
388	ATF_CHECK(prog_validate(insns, insn_count));
389	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == (0xdead&0xbeef));
390}
391
392ATF_TC(bpfjit_alu_or_k);
393ATF_TC_HEAD(bpfjit_alu_or_k, tc)
394{
395	atf_tc_set_md_var(tc, "descr",
396	    "Test JIT compilation of BPF_ALU+BPF_OR+BPF_K");
397}
398
399ATF_TC_BODY(bpfjit_alu_or_k, tc)
400{
401	static struct bpf_insn insns[] = {
402		BPF_STMT(BPF_LD+BPF_IMM, 0xdead0000),
403		BPF_STMT(BPF_ALU+BPF_OR+BPF_K, 0x0000beef),
404		BPF_STMT(BPF_RET+BPF_A, 0)
405	};
406
407	uint8_t pkt[1]; /* the program doesn't read any data */
408
409	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
410
411	RZ(rump_init());
412
413	ATF_CHECK(prog_validate(insns, insn_count));
414	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xdeadbeef);
415}
416
417ATF_TC(bpfjit_alu_lsh_k);
418ATF_TC_HEAD(bpfjit_alu_lsh_k, tc)
419{
420	atf_tc_set_md_var(tc, "descr",
421	    "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_K");
422}
423
424ATF_TC_BODY(bpfjit_alu_lsh_k, tc)
425{
426	static struct bpf_insn insns[] = {
427		BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
428		BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 16),
429		BPF_STMT(BPF_RET+BPF_A, 0)
430	};
431
432	uint8_t pkt[1]; /* the program doesn't read any data */
433
434	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
435
436	RZ(rump_init());
437
438	ATF_CHECK(prog_validate(insns, insn_count));
439	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xbeef0000);
440}
441
442ATF_TC(bpfjit_alu_lsh0_k);
443ATF_TC_HEAD(bpfjit_alu_lsh0_k, tc)
444{
445	atf_tc_set_md_var(tc, "descr",
446	    "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_K with k=0");
447}
448
449ATF_TC_BODY(bpfjit_alu_lsh0_k, tc)
450{
451	static struct bpf_insn insns[] = {
452		BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
453		BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 0),
454		BPF_STMT(BPF_RET+BPF_A, 0)
455	};
456
457	uint8_t pkt[1]; /* the program doesn't read any data */
458
459	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
460
461	RZ(rump_init());
462
463	ATF_CHECK(prog_validate(insns, insn_count));
464	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xdeadbeef);
465}
466
467ATF_TC(bpfjit_alu_rsh_k);
468ATF_TC_HEAD(bpfjit_alu_rsh_k, tc)
469{
470	atf_tc_set_md_var(tc, "descr",
471	    "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_K");
472}
473
474ATF_TC_BODY(bpfjit_alu_rsh_k, tc)
475{
476	static struct bpf_insn insns[] = {
477		BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
478		BPF_STMT(BPF_ALU+BPF_RSH+BPF_K, 16),
479		BPF_STMT(BPF_RET+BPF_A, 0)
480	};
481
482	uint8_t pkt[1]; /* the program doesn't read any data */
483
484	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
485
486	RZ(rump_init());
487
488	ATF_CHECK(prog_validate(insns, insn_count));
489	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0x0000dead);
490}
491
492ATF_TC(bpfjit_alu_rsh0_k);
493ATF_TC_HEAD(bpfjit_alu_rsh0_k, tc)
494{
495	atf_tc_set_md_var(tc, "descr",
496	    "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_K with k=0");
497}
498
499ATF_TC_BODY(bpfjit_alu_rsh0_k, tc)
500{
501	static struct bpf_insn insns[] = {
502		BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
503		BPF_STMT(BPF_ALU+BPF_RSH+BPF_K, 0),
504		BPF_STMT(BPF_RET+BPF_A, 0)
505	};
506
507	uint8_t pkt[1]; /* the program doesn't read any data */
508
509	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
510
511	RZ(rump_init());
512
513	ATF_CHECK(prog_validate(insns, insn_count));
514	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xdeadbeef);
515}
516
517ATF_TC(bpfjit_alu_modulo_k);
518ATF_TC_HEAD(bpfjit_alu_modulo_k, tc)
519{
520	atf_tc_set_md_var(tc, "descr",
521	    "Test JIT compilation of modulo logic of BPF_ALU+BPF_K operations");
522}
523
524ATF_TC_BODY(bpfjit_alu_modulo_k, tc)
525{
526	static struct bpf_insn insns[] = {
527		BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)),
528
529		/* (7FFFFF77 * 0FFFFF77) = 07FFFFB2,F0004951 */
530		BPF_STMT(BPF_ALU+BPF_MUL+BPF_K, UINT32_C(0x0fffff77)),
531
532		/* 07FFFFB2,F0004951 << 1 = 0FFFFF65,E00092A2 */
533		BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 1),
534
535		/* 0FFFFF65,E00092A2 + DDDDDDDD = 0FFFFF66,BDDE707F */
536		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xdddddddd)),
537
538		/* 0FFFFF66,BDDE707F - FFFFFFFF = 0FFFFF65,BDDE7080 */
539		BPF_STMT(BPF_ALU+BPF_SUB+BPF_K, UINT32_C(0xffffffff)),
540
541		/* 0FFFFF65,BDDE7080 | 0000030C = 0FFFFF65,BDDE738C */
542		BPF_STMT(BPF_ALU+BPF_OR+BPF_K, UINT32_C(0x0000030c)),
543
544		/* -0FFFFF65,BDDE738C mod(2^64) = F000009A,42218C74 */
545		BPF_STMT(BPF_ALU+BPF_NEG, 0),
546
547		/* F000009A,42218C74 & FFFFFF0F = F000009A,42218C04 */
548		BPF_STMT(BPF_ALU+BPF_AND+BPF_K, UINT32_C(0xffffff0f)),
549
550		/* F000009A,42218C74 >> 3 = 1E000013,48443180 */
551		/* 00000000,42218C74 >> 3 = 00000000,08443180 */
552		BPF_STMT(BPF_ALU+BPF_RSH+BPF_K, 3),
553
554		/* 00000000,08443180 * 7FFFFF77 = 042218BB,93818280 */
555		BPF_STMT(BPF_ALU+BPF_MUL+BPF_K, UINT32_C(0x7fffff77)),
556
557		/* 042218BB,93818280 / DEAD = 000004C0,71CBBBC3 */
558		/* 00000000,93818280 / DEAD = 00000000,0000A994 */
559		BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, UINT32_C(0xdead)),
560
561		BPF_STMT(BPF_RET+BPF_A, 0)
562	};
563
564	bpfjit_func_t code;
565	uint8_t pkt[1]; /* the program doesn't read any data */
566
567	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
568
569	RZ(rump_init());
570
571	ATF_CHECK(prog_validate(insns, insn_count));
572
573	rump_schedule();
574	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
575	rump_unschedule();
576	ATF_REQUIRE(code != NULL);
577
578	ATF_CHECK(jitcall(code, pkt, 1, 1) != UINT32_C(0x71cbbbc3));
579	ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0x0000a994));
580
581	rump_schedule();
582	rumpns_bpfjit_free_code(code);
583	rump_unschedule();
584}
585
586ATF_TC(bpfjit_alu_add_x);
587ATF_TC_HEAD(bpfjit_alu_add_x, tc)
588{
589	atf_tc_set_md_var(tc, "descr",
590	    "Test JIT compilation of BPF_ALU+BPF_ADD+BPF_X");
591}
592
593ATF_TC_BODY(bpfjit_alu_add_x, tc)
594{
595	static struct bpf_insn insns[] = {
596		BPF_STMT(BPF_LD+BPF_IMM, 3),
597		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2),
598		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
599		BPF_STMT(BPF_RET+BPF_A, 0)
600	};
601
602	uint8_t pkt[1]; /* the program doesn't read any data */
603
604	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
605
606	RZ(rump_init());
607
608	ATF_CHECK(prog_validate(insns, insn_count));
609	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 5);
610}
611
612ATF_TC(bpfjit_alu_sub_x);
613ATF_TC_HEAD(bpfjit_alu_sub_x, tc)
614{
615	atf_tc_set_md_var(tc, "descr",
616	    "Test JIT compilation of BPF_ALU+BPF_SUB+BPF_X");
617}
618
619ATF_TC_BODY(bpfjit_alu_sub_x, tc)
620{
621	static struct bpf_insn insns[] = {
622		BPF_STMT(BPF_LD+BPF_IMM, 1),
623		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2),
624		BPF_STMT(BPF_ALU+BPF_SUB+BPF_X, 0),
625		BPF_STMT(BPF_RET+BPF_A, 0)
626	};
627
628	uint8_t pkt[1]; /* the program doesn't read any data */
629
630	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
631
632	RZ(rump_init());
633
634	ATF_CHECK(prog_validate(insns, insn_count));
635	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX);
636}
637
638ATF_TC(bpfjit_alu_mul_x);
639ATF_TC_HEAD(bpfjit_alu_mul_x, tc)
640{
641	atf_tc_set_md_var(tc, "descr",
642	    "Test JIT compilation of BPF_ALU+BPF_MUL+BPF_X");
643}
644
645ATF_TC_BODY(bpfjit_alu_mul_x, tc)
646{
647	static struct bpf_insn insns[] = {
648		BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)),
649		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
650		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0),
651		BPF_STMT(BPF_RET+BPF_A, 0)
652	};
653
654	uint8_t pkt[1]; /* the program doesn't read any data */
655
656	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
657
658	RZ(rump_init());
659
660	ATF_CHECK(prog_validate(insns, insn_count));
661	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xfffffffd);
662}
663
664ATF_TC(bpfjit_alu_div0_x);
665ATF_TC_HEAD(bpfjit_alu_div0_x, tc)
666{
667	atf_tc_set_md_var(tc, "descr",
668	    "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=0");
669}
670
671ATF_TC_BODY(bpfjit_alu_div0_x, tc)
672{
673	static struct bpf_insn insns[] = {
674		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
675		BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
676		BPF_STMT(BPF_RET+BPF_A, 0)
677	};
678
679	uint8_t pkt[1]; /* the program doesn't read any data */
680
681	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
682
683	RZ(rump_init());
684
685	ATF_CHECK(prog_validate(insns, insn_count));
686	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0);
687}
688
689ATF_TC(bpfjit_alu_div1_x);
690ATF_TC_HEAD(bpfjit_alu_div1_x, tc)
691{
692	atf_tc_set_md_var(tc, "descr",
693	    "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=1");
694}
695
696ATF_TC_BODY(bpfjit_alu_div1_x, tc)
697{
698	static struct bpf_insn insns[] = {
699		BPF_STMT(BPF_LD+BPF_IMM, 7),
700		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1),
701		BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
702		BPF_STMT(BPF_RET+BPF_A, 0)
703	};
704
705	uint8_t pkt[1]; /* the program doesn't read any data */
706
707	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
708
709	RZ(rump_init());
710
711	ATF_CHECK(prog_validate(insns, insn_count));
712	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 7);
713}
714
715ATF_TC(bpfjit_alu_div2_x);
716ATF_TC_HEAD(bpfjit_alu_div2_x, tc)
717{
718	atf_tc_set_md_var(tc, "descr",
719	    "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=2");
720}
721
722ATF_TC_BODY(bpfjit_alu_div2_x, tc)
723{
724	static struct bpf_insn insns[] = {
725		BPF_STMT(BPF_LD+BPF_IMM, 7),
726		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2),
727		BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
728		BPF_STMT(BPF_RET+BPF_A, 0)
729	};
730
731	uint8_t pkt[1]; /* the program doesn't read any data */
732
733	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
734
735	RZ(rump_init());
736
737	ATF_CHECK(prog_validate(insns, insn_count));
738	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 3);
739}
740
741ATF_TC(bpfjit_alu_div4_x);
742ATF_TC_HEAD(bpfjit_alu_div4_x, tc)
743{
744	atf_tc_set_md_var(tc, "descr",
745	    "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=4");
746}
747
748ATF_TC_BODY(bpfjit_alu_div4_x, tc)
749{
750	static struct bpf_insn insns[] = {
751		BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)),
752		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4),
753		BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
754		BPF_STMT(BPF_RET+BPF_A, 0)
755	};
756
757	uint8_t pkt[1]; /* the program doesn't read any data */
758
759	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
760
761	RZ(rump_init());
762
763	ATF_CHECK(prog_validate(insns, insn_count));
764	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0x3fffffff);
765}
766
767ATF_TC(bpfjit_alu_div10_x);
768ATF_TC_HEAD(bpfjit_alu_div10_x, tc)
769{
770	atf_tc_set_md_var(tc, "descr",
771	    "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=10");
772}
773
774ATF_TC_BODY(bpfjit_alu_div10_x, tc)
775{
776	static struct bpf_insn insns[] = {
777		BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)),
778		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 10),
779		BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
780		BPF_STMT(BPF_RET+BPF_A, 0)
781	};
782
783	uint8_t pkt[1]; /* the program doesn't read any data */
784
785	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
786
787	RZ(rump_init());
788
789	ATF_CHECK(prog_validate(insns, insn_count));
790	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 429484384);
791}
792
793ATF_TC(bpfjit_alu_div10000_x);
794ATF_TC_HEAD(bpfjit_alu_div10000_x, tc)
795{
796	atf_tc_set_md_var(tc, "descr",
797	    "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=10000");
798}
799
800ATF_TC_BODY(bpfjit_alu_div10000_x, tc)
801{
802	static struct bpf_insn insns[] = {
803		BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)),
804		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 10000),
805		BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
806		BPF_STMT(BPF_RET+BPF_A, 0)
807	};
808
809	uint8_t pkt[1]; /* the program doesn't read any data */
810
811	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
812
813	RZ(rump_init());
814
815	ATF_CHECK(prog_validate(insns, insn_count));
816	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 429484);
817}
818
819ATF_TC(bpfjit_alu_div7609801_x);
820ATF_TC_HEAD(bpfjit_alu_div7609801_x, tc)
821{
822	atf_tc_set_md_var(tc, "descr",
823	    "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=7609801");
824}
825
826ATF_TC_BODY(bpfjit_alu_div7609801_x, tc)
827{
828	static struct bpf_insn insns[] = {
829		BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294967295)),
830		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(7609801)),
831		BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
832		BPF_STMT(BPF_RET+BPF_A, 0)
833	};
834
835	uint8_t pkt[1]; /* the program doesn't read any data */
836
837	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
838
839	RZ(rump_init());
840
841	ATF_CHECK(prog_validate(insns, insn_count));
842	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 564);
843}
844
845ATF_TC(bpfjit_alu_div80000000_x);
846ATF_TC_HEAD(bpfjit_alu_div80000000_x, tc)
847{
848	atf_tc_set_md_var(tc, "descr",
849	    "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=0x80000000");
850}
851
852ATF_TC_BODY(bpfjit_alu_div80000000_x, tc)
853{
854	static struct bpf_insn insns[] = {
855		BPF_STMT(BPF_LD+BPF_IMM, UINT32_MAX - 33),
856		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0x80000000)),
857		BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
858		BPF_STMT(BPF_RET+BPF_A, 0)
859	};
860
861	uint8_t pkt[1]; /* the program doesn't read any data */
862
863	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
864
865	RZ(rump_init());
866
867	ATF_CHECK(prog_validate(insns, insn_count));
868	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 1);
869}
870
871ATF_TC(bpfjit_alu_and_x);
872ATF_TC_HEAD(bpfjit_alu_and_x, tc)
873{
874	atf_tc_set_md_var(tc, "descr",
875	    "Test JIT compilation of BPF_ALU+BPF_AND+BPF_X");
876}
877
878ATF_TC_BODY(bpfjit_alu_and_x, tc)
879{
880	static struct bpf_insn insns[] = {
881		BPF_STMT(BPF_LD+BPF_IMM, 0xdead),
882		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0xbeef),
883		BPF_STMT(BPF_ALU+BPF_AND+BPF_X, 0),
884		BPF_STMT(BPF_RET+BPF_A, 0)
885	};
886
887	uint8_t pkt[1]; /* the program doesn't read any data */
888
889	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
890
891	RZ(rump_init());
892
893	ATF_CHECK(prog_validate(insns, insn_count));
894	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == (0xdead&0xbeef));
895}
896
897ATF_TC(bpfjit_alu_or_x);
898ATF_TC_HEAD(bpfjit_alu_or_x, tc)
899{
900	atf_tc_set_md_var(tc, "descr",
901	    "Test JIT compilation of BPF_ALU+BPF_OR+BPF_X");
902}
903
904ATF_TC_BODY(bpfjit_alu_or_x, tc)
905{
906	static struct bpf_insn insns[] = {
907		BPF_STMT(BPF_LD+BPF_IMM, 0xdead0000),
908		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0x0000beef),
909		BPF_STMT(BPF_ALU+BPF_OR+BPF_X, 0),
910		BPF_STMT(BPF_RET+BPF_A, 0)
911	};
912
913	uint8_t pkt[1]; /* the program doesn't read any data */
914
915	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
916
917	RZ(rump_init());
918
919	ATF_CHECK(prog_validate(insns, insn_count));
920	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xdeadbeef);
921}
922
923ATF_TC(bpfjit_alu_lsh_x);
924ATF_TC_HEAD(bpfjit_alu_lsh_x, tc)
925{
926	atf_tc_set_md_var(tc, "descr",
927	    "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_X");
928}
929
930ATF_TC_BODY(bpfjit_alu_lsh_x, tc)
931{
932	static struct bpf_insn insns[] = {
933		BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
934		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 16),
935		BPF_STMT(BPF_ALU+BPF_LSH+BPF_X, 0),
936		BPF_STMT(BPF_RET+BPF_A, 0)
937	};
938
939	uint8_t pkt[1]; /* the program doesn't read any data */
940
941	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
942
943	RZ(rump_init());
944
945	ATF_CHECK(prog_validate(insns, insn_count));
946	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xbeef0000);
947}
948
949ATF_TC(bpfjit_alu_lsh0_x);
950ATF_TC_HEAD(bpfjit_alu_lsh0_x, tc)
951{
952	atf_tc_set_md_var(tc, "descr",
953	    "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_X with k=0");
954}
955
956ATF_TC_BODY(bpfjit_alu_lsh0_x, tc)
957{
958	static struct bpf_insn insns[] = {
959		BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
960		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
961		BPF_STMT(BPF_ALU+BPF_LSH+BPF_X, 0),
962		BPF_STMT(BPF_RET+BPF_A, 0)
963	};
964
965	uint8_t pkt[1]; /* the program doesn't read any data */
966
967	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
968
969	RZ(rump_init());
970
971	ATF_CHECK(prog_validate(insns, insn_count));
972	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xdeadbeef);
973}
974
975ATF_TC(bpfjit_alu_rsh_x);
976ATF_TC_HEAD(bpfjit_alu_rsh_x, tc)
977{
978	atf_tc_set_md_var(tc, "descr",
979	    "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_X");
980}
981
982ATF_TC_BODY(bpfjit_alu_rsh_x, tc)
983{
984	static struct bpf_insn insns[] = {
985		BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
986		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 16),
987		BPF_STMT(BPF_ALU+BPF_RSH+BPF_X, 0),
988		BPF_STMT(BPF_RET+BPF_A, 0)
989	};
990
991	uint8_t pkt[1]; /* the program doesn't read any data */
992
993	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
994
995	RZ(rump_init());
996
997	ATF_CHECK(prog_validate(insns, insn_count));
998	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0x0000dead);
999}
1000
1001ATF_TC(bpfjit_alu_rsh0_x);
1002ATF_TC_HEAD(bpfjit_alu_rsh0_x, tc)
1003{
1004	atf_tc_set_md_var(tc, "descr",
1005	    "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_X with k=0");
1006}
1007
1008ATF_TC_BODY(bpfjit_alu_rsh0_x, tc)
1009{
1010	static struct bpf_insn insns[] = {
1011		BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
1012		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
1013		BPF_STMT(BPF_ALU+BPF_RSH+BPF_X, 0),
1014		BPF_STMT(BPF_RET+BPF_A, 0)
1015	};
1016
1017	uint8_t pkt[1]; /* the program doesn't read any data */
1018
1019	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1020
1021	RZ(rump_init());
1022
1023	ATF_CHECK(prog_validate(insns, insn_count));
1024	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xdeadbeef);
1025}
1026
1027ATF_TC(bpfjit_alu_modulo_x);
1028ATF_TC_HEAD(bpfjit_alu_modulo_x, tc)
1029{
1030	atf_tc_set_md_var(tc, "descr",
1031	    "Test JIT compilation of modulo logic of BPF_ALU+BPF_X operations");
1032}
1033
1034ATF_TC_BODY(bpfjit_alu_modulo_x, tc)
1035{
1036	static struct bpf_insn insns[] = {
1037		BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)),
1038
1039		/* (7FFFFF77 * 0FFFFF77) = 07FFFFB2,F0004951 */
1040		BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0x0fffff77)),
1041		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0),
1042
1043		/* 07FFFFB2,F0004951 << 1 = 0FFFFF65,E00092A2 */
1044		BPF_STMT(BPF_LDX+BPF_W+BPF_K, 1),
1045		BPF_STMT(BPF_ALU+BPF_LSH+BPF_X, 0),
1046
1047		/* 0FFFFF65,E00092A2 + DDDDDDDD = 0FFFFF66,BDDE707F */
1048		BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xdddddddd)),
1049		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
1050
1051		/* 0FFFFF66,BDDE707F - FFFFFFFF = 0FFFFF65,BDDE7080 */
1052		BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xffffffff)),
1053		BPF_STMT(BPF_ALU+BPF_SUB+BPF_X, 0),
1054
1055		/* 0FFFFF65,BDDE7080 | 0000030C = 0FFFFF65,BDDE738C */
1056		BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0x0000030c)),
1057		BPF_STMT(BPF_ALU+BPF_OR+BPF_X, 0),
1058
1059		/* -0FFFFF65,BDDE738C mod(2^64) = F000009A,42218C74 */
1060		BPF_STMT(BPF_ALU+BPF_NEG, 0),
1061
1062		/* F000009A,42218C74 & FFFFFF0F = F000009A,42218C04 */
1063		BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xffffff0f)),
1064		BPF_STMT(BPF_ALU+BPF_AND+BPF_X, 0),
1065
1066		/* F000009A,42218C74 >> 3 = 1E000013,48443180 */
1067		/* 00000000,42218C74 >> 3 = 00000000,08443180 */
1068		BPF_STMT(BPF_LDX+BPF_W+BPF_K, 3),
1069		BPF_STMT(BPF_ALU+BPF_RSH+BPF_X, 0),
1070
1071		/* 00000000,08443180 * 7FFFFF77 = 042218BB,93818280 */
1072		BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0x7fffff77)),
1073		BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0),
1074
1075		/* 042218BB,93818280 / DEAD = 000004C0,71CBBBC3 */
1076		/* 00000000,93818280 / DEAD = 00000000,0000A994 */
1077		BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xdead)),
1078		BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
1079
1080		BPF_STMT(BPF_RET+BPF_A, 0)
1081	};
1082
1083	bpfjit_func_t code;
1084	uint8_t pkt[1]; /* the program doesn't read any data */
1085
1086	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1087
1088	RZ(rump_init());
1089
1090	ATF_CHECK(prog_validate(insns, insn_count));
1091
1092	rump_schedule();
1093	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
1094	rump_unschedule();
1095	ATF_REQUIRE(code != NULL);
1096
1097	ATF_CHECK(jitcall(code, pkt, 1, 1) != UINT32_C(0x71cbbbc3));
1098	ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0x0000a994));
1099
1100	rump_schedule();
1101	rumpns_bpfjit_free_code(code);
1102	rump_unschedule();
1103}
1104
1105ATF_TC(bpfjit_alu_neg);
1106ATF_TC_HEAD(bpfjit_alu_neg, tc)
1107{
1108	atf_tc_set_md_var(tc, "descr",
1109	    "Test JIT compilation of BPF_ALU+BPF_NEG");
1110}
1111
1112ATF_TC_BODY(bpfjit_alu_neg, tc)
1113{
1114	static struct bpf_insn insns[] = {
1115		BPF_STMT(BPF_LD+BPF_IMM, 777),
1116		BPF_STMT(BPF_ALU+BPF_NEG, 0),
1117		BPF_STMT(BPF_RET+BPF_A, 0)
1118	};
1119
1120	uint8_t pkt[1]; /* the program doesn't read any data */
1121
1122	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1123
1124	RZ(rump_init());
1125
1126	ATF_CHECK(prog_validate(insns, insn_count));
1127	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0u-777u);
1128}
1129
1130ATF_TC(bpfjit_jmp_ja);
1131ATF_TC_HEAD(bpfjit_jmp_ja, tc)
1132{
1133	atf_tc_set_md_var(tc, "descr",
1134	    "Test JIT compilation of BPF_JMP+BPF_JA");
1135}
1136
1137ATF_TC_BODY(bpfjit_jmp_ja, tc)
1138{
1139	static struct bpf_insn insns[] = {
1140		BPF_STMT(BPF_JMP+BPF_JA, 1),
1141		BPF_STMT(BPF_RET+BPF_K, 0),
1142		BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
1143		BPF_STMT(BPF_RET+BPF_K, 1),
1144		BPF_STMT(BPF_RET+BPF_K, 2),
1145		BPF_STMT(BPF_RET+BPF_K, 3),
1146	};
1147
1148	uint8_t pkt[1]; /* the program doesn't read any data */
1149
1150	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1151
1152	RZ(rump_init());
1153
1154	ATF_CHECK(prog_validate(insns, insn_count));
1155	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX);
1156}
1157
1158ATF_TC(bpfjit_jmp_jgt_k);
1159ATF_TC_HEAD(bpfjit_jmp_jgt_k, tc)
1160{
1161	atf_tc_set_md_var(tc, "descr",
1162	    "Test JIT compilation of BPF_JMP+BPF_JGT+BPF_K");
1163}
1164
1165ATF_TC_BODY(bpfjit_jmp_jgt_k, tc)
1166{
1167	static struct bpf_insn insns[] = {
1168		BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
1169		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 7, 0, 1),
1170		BPF_STMT(BPF_RET+BPF_K, 0),
1171		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 2, 2, 0),
1172		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 9, 0, 0),
1173		BPF_STMT(BPF_RET+BPF_K, 1),
1174		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 4, 1, 1),
1175		BPF_STMT(BPF_RET+BPF_K, 2),
1176		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 6, 2, 3),
1177		BPF_STMT(BPF_RET+BPF_K, 3),
1178		BPF_STMT(BPF_RET+BPF_K, 4),
1179		BPF_STMT(BPF_RET+BPF_K, 5),
1180		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 5, 3, 1),
1181		BPF_STMT(BPF_RET+BPF_K, 6),
1182		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 0, 0, 0),
1183		BPF_STMT(BPF_RET+BPF_K, 7),
1184		BPF_STMT(BPF_RET+BPF_K, 8)
1185	};
1186
1187	bpfjit_func_t code;
1188	uint8_t pkt[8]; /* the program doesn't read any data */
1189
1190	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1191
1192	RZ(rump_init());
1193
1194	ATF_CHECK(prog_validate(insns, insn_count));
1195
1196	rump_schedule();
1197	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
1198	rump_unschedule();
1199	ATF_REQUIRE(code != NULL);
1200
1201	ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
1202	ATF_CHECK(jitcall(code, pkt, 2, 2) == 1);
1203	ATF_CHECK(jitcall(code, pkt, 3, 3) == 7);
1204	ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
1205	ATF_CHECK(jitcall(code, pkt, 5, 5) == 7);
1206	ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
1207	ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
1208	ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
1209
1210	rump_schedule();
1211	rumpns_bpfjit_free_code(code);
1212	rump_unschedule();
1213}
1214
1215ATF_TC(bpfjit_jmp_jge_k);
1216ATF_TC_HEAD(bpfjit_jmp_jge_k, tc)
1217{
1218	atf_tc_set_md_var(tc, "descr",
1219	    "Test JIT compilation of BPF_JMP+BPF_JGE+BPF_K");
1220}
1221
1222ATF_TC_BODY(bpfjit_jmp_jge_k, tc)
1223{
1224	static struct bpf_insn insns[] = {
1225		BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
1226		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 8, 0, 1),
1227		BPF_STMT(BPF_RET+BPF_K, 0),
1228		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 3, 2, 0),
1229		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 9, 0, 0),
1230		BPF_STMT(BPF_RET+BPF_K, 1),
1231		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 5, 1, 1),
1232		BPF_STMT(BPF_RET+BPF_K, 2),
1233		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 7, 2, 3),
1234		BPF_STMT(BPF_RET+BPF_K, 3),
1235		BPF_STMT(BPF_RET+BPF_K, 4),
1236		BPF_STMT(BPF_RET+BPF_K, 5),
1237		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 6, 3, 1),
1238		BPF_STMT(BPF_RET+BPF_K, 6),
1239		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 1, 0, 0),
1240		BPF_STMT(BPF_RET+BPF_K, 7),
1241		BPF_STMT(BPF_RET+BPF_K, 8)
1242	};
1243
1244	bpfjit_func_t code;
1245	uint8_t pkt[8]; /* the program doesn't read any data */
1246
1247	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1248
1249	RZ(rump_init());
1250
1251	ATF_CHECK(prog_validate(insns, insn_count));
1252
1253	rump_schedule();
1254	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
1255	rump_unschedule();
1256	ATF_REQUIRE(code != NULL);
1257
1258	ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
1259	ATF_CHECK(jitcall(code, pkt, 2, 2) == 1);
1260	ATF_CHECK(jitcall(code, pkt, 3, 3) == 7);
1261	ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
1262	ATF_CHECK(jitcall(code, pkt, 5, 5) == 7);
1263	ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
1264	ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
1265	ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
1266
1267	rump_schedule();
1268	rumpns_bpfjit_free_code(code);
1269	rump_unschedule();
1270}
1271
1272ATF_TC(bpfjit_jmp_jeq_k);
1273ATF_TC_HEAD(bpfjit_jmp_jeq_k, tc)
1274{
1275	atf_tc_set_md_var(tc, "descr",
1276	    "Test JIT compilation of BPF_JMP+BPF_JEQ+BPF_K");
1277}
1278
1279ATF_TC_BODY(bpfjit_jmp_jeq_k, tc)
1280{
1281	static struct bpf_insn insns[] = {
1282		BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
1283		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 8, 0, 1),
1284		BPF_STMT(BPF_RET+BPF_K, 0),
1285		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 3, 1, 0),
1286		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 9, 1, 1),
1287		BPF_STMT(BPF_RET+BPF_K, 1),
1288		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 5, 1, 1),
1289		BPF_STMT(BPF_RET+BPF_K, 2),
1290		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 7, 2, 3),
1291		BPF_STMT(BPF_RET+BPF_K, 3),
1292		BPF_STMT(BPF_RET+BPF_K, 4),
1293		BPF_STMT(BPF_RET+BPF_K, 5),
1294		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 6, 3, 1),
1295		BPF_STMT(BPF_RET+BPF_K, 6),
1296		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 1, 0, 0),
1297		BPF_STMT(BPF_RET+BPF_K, 7),
1298		BPF_STMT(BPF_RET+BPF_K, 8)
1299	};
1300
1301	bpfjit_func_t code;
1302	uint8_t pkt[8]; /* the program doesn't read any data */
1303
1304	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1305
1306	RZ(rump_init());
1307
1308	ATF_CHECK(prog_validate(insns, insn_count));
1309
1310	rump_schedule();
1311	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
1312	rump_unschedule();
1313	ATF_REQUIRE(code != NULL);
1314
1315	ATF_CHECK(jitcall(code, pkt, 1, 1) == 7);
1316	ATF_CHECK(jitcall(code, pkt, 2, 2) == 7);
1317	ATF_CHECK(jitcall(code, pkt, 3, 3) == 1);
1318	ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
1319	ATF_CHECK(jitcall(code, pkt, 5, 5) == 7);
1320	ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
1321	ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
1322	ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
1323
1324	rump_schedule();
1325	rumpns_bpfjit_free_code(code);
1326	rump_unschedule();
1327}
1328
1329ATF_TC(bpfjit_jmp_jset_k);
1330ATF_TC_HEAD(bpfjit_jmp_jset_k, tc)
1331{
1332	atf_tc_set_md_var(tc, "descr",
1333	    "Test JIT compilation of BPF_JMP+BPF_JSET+BPF_K");
1334}
1335
1336ATF_TC_BODY(bpfjit_jmp_jset_k, tc)
1337{
1338	static struct bpf_insn insns[] = {
1339		BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
1340		BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 8, 0, 1),
1341		BPF_STMT(BPF_RET+BPF_K, 0),
1342		BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 4, 2, 0),
1343		BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 3, 0, 0),
1344		BPF_STMT(BPF_RET+BPF_K, 1),
1345		BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 2, 1, 1),
1346		BPF_STMT(BPF_RET+BPF_K, 2),
1347		BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 1, 2, 3),
1348		BPF_STMT(BPF_RET+BPF_K, 3),
1349		BPF_STMT(BPF_RET+BPF_K, 4),
1350		BPF_STMT(BPF_RET+BPF_K, 5),
1351		BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 2, 3, 1),
1352		BPF_STMT(BPF_RET+BPF_K, 6),
1353		BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 7, 0, 0),
1354		BPF_STMT(BPF_RET+BPF_K, 7),
1355		BPF_STMT(BPF_RET+BPF_K, 8)
1356	};
1357
1358	bpfjit_func_t code;
1359	uint8_t pkt[8]; /* the program doesn't read any data */
1360
1361	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1362
1363	RZ(rump_init());
1364
1365	ATF_CHECK(prog_validate(insns, insn_count));
1366
1367	rump_schedule();
1368	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
1369	rump_unschedule();
1370	ATF_REQUIRE(code != NULL);
1371
1372	ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
1373	ATF_CHECK(jitcall(code, pkt, 2, 2) == 1);
1374	ATF_CHECK(jitcall(code, pkt, 3, 3) == 1);
1375	ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
1376	ATF_CHECK(jitcall(code, pkt, 5, 5) == 5);
1377	ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
1378	ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
1379	ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
1380
1381	rump_schedule();
1382	rumpns_bpfjit_free_code(code);
1383	rump_unschedule();
1384}
1385
1386ATF_TC(bpfjit_jmp_modulo_k);
1387ATF_TC_HEAD(bpfjit_jmp_modulo_k, tc)
1388{
1389	atf_tc_set_md_var(tc, "descr",
1390	    "Test JIT compilation of modulo logic of BPF_JMP+BPF_K operations");
1391}
1392
1393ATF_TC_BODY(bpfjit_jmp_modulo_k, tc)
1394{
1395	static struct bpf_insn insns[] = {
1396		BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)),
1397		BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 4),
1398		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xfffff770), 1, 0),
1399		BPF_STMT(BPF_RET+BPF_K, 0),
1400		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xfffff770), 0, 1),
1401		BPF_STMT(BPF_RET+BPF_K, 1),
1402		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xfffff771), 0, 1),
1403		BPF_STMT(BPF_RET+BPF_K, 2),
1404		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xfffff770), 0, 3),
1405		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xfffff770), 2, 0),
1406		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xfffff771), 1, 0),
1407		BPF_STMT(BPF_JMP+BPF_JA, 1),
1408		BPF_STMT(BPF_RET+BPF_K, 3),
1409
1410		/* FFFFF770+FFFFF770 = 00000001,FFFFEEE0 */
1411		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xfffff770)),
1412
1413		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xffffeee0), 1, 0),
1414		BPF_STMT(BPF_RET+BPF_K, 4),
1415		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xffffeee0), 0, 1),
1416		BPF_STMT(BPF_RET+BPF_K, 5),
1417		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xffffeee1), 0, 1),
1418		BPF_STMT(BPF_RET+BPF_K, 6),
1419		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xffffeee0), 0, 3),
1420		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xffffeee0), 2, 0),
1421		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xffffeee1), 1, 0),
1422		BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
1423		BPF_STMT(BPF_RET+BPF_K, 7)
1424	};
1425
1426	uint8_t pkt[1]; /* the program doesn't read any data */
1427
1428	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1429
1430	RZ(rump_init());
1431
1432	ATF_CHECK(prog_validate(insns, insn_count));
1433	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX);
1434}
1435
1436ATF_TC(bpfjit_jmp_jgt_x);
1437ATF_TC_HEAD(bpfjit_jmp_jgt_x, tc)
1438{
1439	atf_tc_set_md_var(tc, "descr",
1440	    "Test JIT compilation of BPF_JMP+BPF_JGT+BPF_X");
1441}
1442
1443ATF_TC_BODY(bpfjit_jmp_jgt_x, tc)
1444{
1445	static struct bpf_insn insns[] = {
1446		BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
1447		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7),
1448		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1),
1449		BPF_STMT(BPF_RET+BPF_K, 0),
1450		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2),
1451		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0),
1452		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9),
1453		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 0),
1454		BPF_STMT(BPF_RET+BPF_K, 1),
1455		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4),
1456		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 1, 1),
1457		BPF_STMT(BPF_RET+BPF_K, 2),
1458		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6),
1459		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 2, 3),
1460		BPF_STMT(BPF_RET+BPF_K, 3),
1461		BPF_STMT(BPF_RET+BPF_K, 4),
1462		BPF_STMT(BPF_RET+BPF_K, 5),
1463		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
1464		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 4, 1),
1465		BPF_STMT(BPF_RET+BPF_K, 6),
1466		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
1467		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 0),
1468		BPF_STMT(BPF_RET+BPF_K, 7),
1469		BPF_STMT(BPF_RET+BPF_K, 8)
1470	};
1471
1472	bpfjit_func_t code;
1473	uint8_t pkt[8]; /* the program doesn't read any data */
1474
1475	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1476
1477	RZ(rump_init());
1478
1479	ATF_CHECK(prog_validate(insns, insn_count));
1480
1481	rump_schedule();
1482	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
1483	rump_unschedule();
1484	ATF_REQUIRE(code != NULL);
1485
1486	ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
1487	ATF_CHECK(jitcall(code, pkt, 2, 2) == 1);
1488	ATF_CHECK(jitcall(code, pkt, 3, 3) == 7);
1489	ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
1490	ATF_CHECK(jitcall(code, pkt, 5, 5) == 7);
1491	ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
1492	ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
1493	ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
1494
1495	rump_schedule();
1496	rumpns_bpfjit_free_code(code);
1497	rump_unschedule();
1498}
1499
1500ATF_TC(bpfjit_jmp_jge_x);
1501ATF_TC_HEAD(bpfjit_jmp_jge_x, tc)
1502{
1503	atf_tc_set_md_var(tc, "descr",
1504	    "Test JIT compilation of BPF_JMP+BPF_JGE+BPF_X");
1505}
1506
1507ATF_TC_BODY(bpfjit_jmp_jge_x, tc)
1508{
1509	static struct bpf_insn insns[] = {
1510		BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
1511		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 8),
1512		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1),
1513		BPF_STMT(BPF_RET+BPF_K, 0),
1514		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
1515		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 3, 0),
1516		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9),
1517		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 0),
1518		BPF_STMT(BPF_RET+BPF_K, 1),
1519		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
1520		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 1),
1521		BPF_STMT(BPF_RET+BPF_K, 2),
1522		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7),
1523		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 2, 3),
1524		BPF_STMT(BPF_RET+BPF_K, 3),
1525		BPF_STMT(BPF_RET+BPF_K, 4),
1526		BPF_STMT(BPF_RET+BPF_K, 5),
1527		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6),
1528		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 4, 1),
1529		BPF_STMT(BPF_RET+BPF_K, 6),
1530		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1),
1531		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 0),
1532		BPF_STMT(BPF_RET+BPF_K, 7),
1533		BPF_STMT(BPF_RET+BPF_K, 8)
1534	};
1535
1536	bpfjit_func_t code;
1537	uint8_t pkt[8]; /* the program doesn't read any data */
1538
1539	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1540
1541	RZ(rump_init());
1542
1543	ATF_CHECK(prog_validate(insns, insn_count));
1544
1545	rump_schedule();
1546	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
1547	rump_unschedule();
1548	ATF_REQUIRE(code != NULL);
1549
1550	ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
1551	ATF_CHECK(jitcall(code, pkt, 2, 2) == 1);
1552	ATF_CHECK(jitcall(code, pkt, 3, 3) == 7);
1553	ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
1554	ATF_CHECK(jitcall(code, pkt, 5, 5) == 7);
1555	ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
1556	ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
1557	ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
1558
1559	rump_schedule();
1560	rumpns_bpfjit_free_code(code);
1561	rump_unschedule();
1562}
1563
1564ATF_TC(bpfjit_jmp_jeq_x);
1565ATF_TC_HEAD(bpfjit_jmp_jeq_x, tc)
1566{
1567	atf_tc_set_md_var(tc, "descr",
1568	    "Test JIT compilation of BPF_JMP+BPF_JEQ+BPF_X");
1569}
1570
1571ATF_TC_BODY(bpfjit_jmp_jeq_x, tc)
1572{
1573	static struct bpf_insn insns[] = {
1574		BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
1575		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 8),
1576		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1),
1577		BPF_STMT(BPF_RET+BPF_K, 0),
1578		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
1579		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 2, 0),
1580		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9),
1581		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 1),
1582		BPF_STMT(BPF_RET+BPF_K, 1),
1583		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
1584		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 1),
1585		BPF_STMT(BPF_RET+BPF_K, 2),
1586		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7),
1587		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 2, 3),
1588		BPF_STMT(BPF_RET+BPF_K, 3),
1589		BPF_STMT(BPF_RET+BPF_K, 4),
1590		BPF_STMT(BPF_RET+BPF_K, 5),
1591		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6),
1592		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 3, 1),
1593		BPF_STMT(BPF_RET+BPF_K, 6),
1594		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 1, 0, 0),
1595		BPF_STMT(BPF_RET+BPF_K, 7),
1596		BPF_STMT(BPF_RET+BPF_K, 8)
1597	};
1598
1599	bpfjit_func_t code;
1600	uint8_t pkt[8]; /* the program doesn't read any data */
1601
1602	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1603
1604	RZ(rump_init());
1605
1606	ATF_CHECK(prog_validate(insns, insn_count));
1607
1608	rump_schedule();
1609	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
1610	rump_unschedule();
1611	ATF_REQUIRE(code != NULL);
1612
1613	ATF_CHECK(jitcall(code, pkt, 1, 1) == 7);
1614	ATF_CHECK(jitcall(code, pkt, 2, 2) == 7);
1615	ATF_CHECK(jitcall(code, pkt, 3, 3) == 1);
1616	ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
1617	ATF_CHECK(jitcall(code, pkt, 5, 5) == 7);
1618	ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
1619	ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
1620	ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
1621
1622	rump_schedule();
1623	rumpns_bpfjit_free_code(code);
1624	rump_unschedule();
1625}
1626
1627ATF_TC(bpfjit_jmp_jset_x);
1628ATF_TC_HEAD(bpfjit_jmp_jset_x, tc)
1629{
1630	atf_tc_set_md_var(tc, "descr",
1631	    "Test JIT compilation of BPF_JMP+BPF_JSET+BPF_X");
1632}
1633
1634ATF_TC_BODY(bpfjit_jmp_jset_x, tc)
1635{
1636	static struct bpf_insn insns[] = {
1637		BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
1638		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 8),
1639		BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 0, 1),
1640		BPF_STMT(BPF_RET+BPF_K, 0),
1641		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4),
1642		BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 2, 0),
1643		BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 3, 0, 0),
1644		BPF_STMT(BPF_RET+BPF_K, 1),
1645		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2),
1646		BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 1, 1),
1647		BPF_STMT(BPF_RET+BPF_K, 2),
1648		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1),
1649		BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 2, 3),
1650		BPF_STMT(BPF_RET+BPF_K, 3),
1651		BPF_STMT(BPF_RET+BPF_K, 4),
1652		BPF_STMT(BPF_RET+BPF_K, 5),
1653		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2),
1654		BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 4, 1),
1655		BPF_STMT(BPF_RET+BPF_K, 6),
1656		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7),
1657		BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 0, 0),
1658		BPF_STMT(BPF_RET+BPF_K, 7),
1659		BPF_STMT(BPF_RET+BPF_K, 8)
1660	};
1661
1662	bpfjit_func_t code;
1663	uint8_t pkt[8]; /* the program doesn't read any data */
1664
1665	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1666
1667	RZ(rump_init());
1668
1669	ATF_CHECK(prog_validate(insns, insn_count));
1670
1671	rump_schedule();
1672	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
1673	rump_unschedule();
1674	ATF_REQUIRE(code != NULL);
1675
1676	ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
1677	ATF_CHECK(jitcall(code, pkt, 2, 2) == 1);
1678	ATF_CHECK(jitcall(code, pkt, 3, 3) == 1);
1679	ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
1680	ATF_CHECK(jitcall(code, pkt, 5, 5) == 5);
1681	ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
1682	ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
1683	ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
1684
1685	rump_schedule();
1686	rumpns_bpfjit_free_code(code);
1687	rump_unschedule();
1688}
1689
1690ATF_TC(bpfjit_jmp_modulo_x);
1691ATF_TC_HEAD(bpfjit_jmp_modulo_x, tc)
1692{
1693	atf_tc_set_md_var(tc, "descr",
1694	    "Test JIT compilation of modulo logic of BPF_JMP+BPF_X operations");
1695}
1696
1697ATF_TC_BODY(bpfjit_jmp_modulo_x, tc)
1698{
1699	static struct bpf_insn insns[] = {
1700		BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)),
1701		/* FFFFF770 << 4 = FFFFF770 */
1702		BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 4),
1703
1704		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff770)),
1705		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
1706		BPF_STMT(BPF_RET+BPF_K, 0),
1707		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1),
1708		BPF_STMT(BPF_RET+BPF_K, 1),
1709		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff771)),
1710		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1),
1711		BPF_STMT(BPF_RET+BPF_K, 2),
1712		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff770)),
1713		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 4),
1714		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0),
1715		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff771)),
1716		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 0),
1717		BPF_STMT(BPF_JMP+BPF_JA, 1),
1718		BPF_STMT(BPF_RET+BPF_K, 3),
1719
1720		/* FFFFF770+FFFFF770 = 00000001,FFFFEEE0 */
1721		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xfffff770)),
1722
1723		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee0)),
1724		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
1725		BPF_STMT(BPF_RET+BPF_K, 4),
1726		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1),
1727		BPF_STMT(BPF_RET+BPF_K, 5),
1728		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee1)),
1729		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1),
1730		BPF_STMT(BPF_RET+BPF_K, 6),
1731		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee0)),
1732		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 4),
1733		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0),
1734		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee1)),
1735		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 0),
1736		BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
1737		BPF_STMT(BPF_RET+BPF_K, 7)
1738	};
1739
1740	uint8_t pkt[1]; /* the program doesn't read any data */
1741
1742	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
1743
1744	RZ(rump_init());
1745
1746	ATF_CHECK(prog_validate(insns, insn_count));
1747	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX);
1748}
1749
1750ATF_TC(bpfjit_ld_abs);
1751ATF_TC_HEAD(bpfjit_ld_abs, tc)
1752{
1753	atf_tc_set_md_var(tc, "descr",
1754	    "Test JIT compilation of BPF_LD+BPF_ABS");
1755}
1756
1757ATF_TC_BODY(bpfjit_ld_abs, tc)
1758{
1759	static struct bpf_insn insns[3][2] = {
1760		{
1761			BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 5),
1762			BPF_STMT(BPF_RET+BPF_A, 0)
1763		},
1764		{
1765			BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 5),
1766			BPF_STMT(BPF_RET+BPF_A, 0)
1767		},
1768		{
1769			BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 5),
1770			BPF_STMT(BPF_RET+BPF_A, 0)
1771		}
1772	};
1773
1774	static size_t lengths[3] = { 1, 2, 4 };
1775	static unsigned int expected[3] = { 0xde, 0xdead, 0xdeadbeef };
1776
1777	size_t i, l;
1778	uint8_t *pkt = deadbeef_at_5;
1779	size_t pktsize = sizeof(deadbeef_at_5);
1780
1781	size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]);
1782
1783	RZ(rump_init());
1784
1785	for (i = 0; i < 3; i++) {
1786		bpfjit_func_t code;
1787
1788		ATF_CHECK(prog_validate(insns[i], insn_count));
1789
1790		rump_schedule();
1791		code = rumpns_bpfjit_generate_code(NULL, insns[i], insn_count);
1792		rump_unschedule();
1793		ATF_REQUIRE(code != NULL);
1794
1795		for (l = 1; l < 5 + lengths[i]; l++) {
1796			ATF_CHECK(jitcall(code, pkt, l, l) == 0);
1797			ATF_CHECK(jitcall(code, pkt, pktsize, l) == 0);
1798		}
1799
1800		l = 5 + lengths[i];
1801		ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]);
1802		ATF_CHECK(jitcall(code, pkt, pktsize, l) == expected[i]);
1803
1804		l = pktsize;
1805		ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]);
1806
1807		rump_schedule();
1808		rumpns_bpfjit_free_code(code);
1809		rump_unschedule();
1810	}
1811}
1812
1813ATF_TC(bpfjit_ld_abs_k_overflow);
1814ATF_TC_HEAD(bpfjit_ld_abs_k_overflow, tc)
1815{
1816	atf_tc_set_md_var(tc, "descr",
1817	    "Test JIT compilation of BPF_LD+BPF_ABS with overflow in k+4");
1818}
1819
1820ATF_TC_BODY(bpfjit_ld_abs_k_overflow, tc)
1821{
1822	static struct bpf_insn insns[12][3] = {
1823		{
1824			BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX),
1825			BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1826			BPF_STMT(BPF_RET+BPF_K, 1)
1827		},
1828		{
1829			BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX - 1),
1830			BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1831			BPF_STMT(BPF_RET+BPF_K, 1)
1832		},
1833		{
1834			BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX),
1835			BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1836			BPF_STMT(BPF_RET+BPF_K, 1)
1837		},
1838		{
1839			BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 1),
1840			BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1841			BPF_STMT(BPF_RET+BPF_K, 1)
1842		},
1843		{
1844			BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 2),
1845			BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1846			BPF_STMT(BPF_RET+BPF_K, 1)
1847		},
1848		{
1849			BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 3),
1850			BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1851			BPF_STMT(BPF_RET+BPF_K, 1)
1852		},
1853		{
1854			BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1855			BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX),
1856			BPF_STMT(BPF_RET+BPF_K, 1)
1857		},
1858		{
1859			BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1860			BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX - 1),
1861			BPF_STMT(BPF_RET+BPF_K, 1)
1862		},
1863		{
1864			BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1865			BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX),
1866			BPF_STMT(BPF_RET+BPF_K, 1)
1867		},
1868		{
1869			BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1870			BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 1),
1871			BPF_STMT(BPF_RET+BPF_K, 1)
1872		},
1873		{
1874			BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1875			BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 2),
1876			BPF_STMT(BPF_RET+BPF_K, 1)
1877		},
1878		{
1879			BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
1880			BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 3),
1881			BPF_STMT(BPF_RET+BPF_K, 1)
1882		}
1883	};
1884
1885	int i;
1886	uint8_t pkt[8] = { 0 };
1887
1888	size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]);
1889
1890	RZ(rump_init());
1891
1892	for (i = 0; i < 3; i++) {
1893		ATF_CHECK(prog_validate(insns[i], insn_count));
1894		ATF_CHECK(exec_prog(insns[i], insn_count, pkt, 8) == 0);
1895	}
1896}
1897
1898ATF_TC(bpfjit_ld_ind);
1899ATF_TC_HEAD(bpfjit_ld_ind, tc)
1900{
1901	atf_tc_set_md_var(tc, "descr",
1902	    "Test JIT compilation of BPF_LD+BPF_IND");
1903}
1904
1905ATF_TC_BODY(bpfjit_ld_ind, tc)
1906{
1907	static struct bpf_insn insns[6][3] = {
1908		{
1909			BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
1910			BPF_STMT(BPF_LD+BPF_B+BPF_IND, 2),
1911			BPF_STMT(BPF_RET+BPF_A, 0)
1912		},
1913		{
1914			BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
1915			BPF_STMT(BPF_LD+BPF_H+BPF_IND, 2),
1916			BPF_STMT(BPF_RET+BPF_A, 0)
1917		},
1918		{
1919			BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
1920			BPF_STMT(BPF_LD+BPF_W+BPF_IND, 2),
1921			BPF_STMT(BPF_RET+BPF_A, 0)
1922		},
1923		{
1924			BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
1925			BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0),
1926			BPF_STMT(BPF_RET+BPF_A, 0)
1927		},
1928		{
1929			BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
1930			BPF_STMT(BPF_LD+BPF_H+BPF_IND, 0),
1931			BPF_STMT(BPF_RET+BPF_A, 0)
1932		},
1933		{
1934			BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
1935			BPF_STMT(BPF_LD+BPF_W+BPF_IND, 0),
1936			BPF_STMT(BPF_RET+BPF_A, 0)
1937		}
1938	};
1939
1940	static size_t lengths[6] = { 1, 2, 4, 1, 2, 4 };
1941
1942	static unsigned int expected[6] = {
1943		0xde, 0xdead, 0xdeadbeef,
1944		0xde, 0xdead, 0xdeadbeef
1945	};
1946
1947	size_t i, l;
1948	uint8_t *pkt = deadbeef_at_5;
1949	size_t pktsize = sizeof(deadbeef_at_5);
1950
1951	size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]);
1952
1953	RZ(rump_init());
1954
1955	for (i = 0; i < 3; i++) {
1956		bpfjit_func_t code;
1957
1958		ATF_CHECK(prog_validate(insns[i], insn_count));
1959
1960		rump_schedule();
1961		code = rumpns_bpfjit_generate_code(NULL, insns[i], insn_count);
1962		rump_unschedule();
1963		ATF_REQUIRE(code != NULL);
1964
1965		for (l = 1; l < 5 + lengths[i]; l++) {
1966			ATF_CHECK(jitcall(code, pkt, l, l) == 0);
1967			ATF_CHECK(jitcall(code, pkt, pktsize, l) == 0);
1968		}
1969
1970		l = 5 + lengths[i];
1971		ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]);
1972		ATF_CHECK(jitcall(code, pkt, pktsize, l) == expected[i]);
1973
1974		l = pktsize;
1975		ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]);
1976
1977		rump_schedule();
1978		rumpns_bpfjit_free_code(code);
1979		rump_unschedule();
1980	}
1981}
1982
1983ATF_TC(bpfjit_ld_ind_k_overflow);
1984ATF_TC_HEAD(bpfjit_ld_ind_k_overflow, tc)
1985{
1986	atf_tc_set_md_var(tc, "descr",
1987	    "Test JIT compilation of BPF_LD+BPF_IND with overflow in k+4");
1988}
1989
1990ATF_TC_BODY(bpfjit_ld_ind_k_overflow, tc)
1991{
1992	static struct bpf_insn insns[12][3] = {
1993		{
1994			BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX),
1995			BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
1996			BPF_STMT(BPF_RET+BPF_K, 1)
1997		},
1998		{
1999			BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX - 1),
2000			BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2001			BPF_STMT(BPF_RET+BPF_K, 1)
2002		},
2003		{
2004			BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX),
2005			BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2006			BPF_STMT(BPF_RET+BPF_K, 1)
2007		},
2008		{
2009			BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 1),
2010			BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2011			BPF_STMT(BPF_RET+BPF_K, 1)
2012		},
2013		{
2014			BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 2),
2015			BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2016			BPF_STMT(BPF_RET+BPF_K, 1)
2017		},
2018		{
2019			BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 3),
2020			BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2021			BPF_STMT(BPF_RET+BPF_K, 1)
2022		},
2023		{
2024			BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2025			BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX),
2026			BPF_STMT(BPF_RET+BPF_K, 1)
2027		},
2028		{
2029			BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2030			BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX - 1),
2031			BPF_STMT(BPF_RET+BPF_K, 1)
2032		},
2033		{
2034			BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2035			BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX),
2036			BPF_STMT(BPF_RET+BPF_K, 1)
2037		},
2038		{
2039			BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2040			BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 1),
2041			BPF_STMT(BPF_RET+BPF_K, 1)
2042		},
2043		{
2044			BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2045			BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 2),
2046			BPF_STMT(BPF_RET+BPF_K, 1)
2047		},
2048		{
2049			BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2050			BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 3),
2051			BPF_STMT(BPF_RET+BPF_K, 1)
2052		}
2053	};
2054
2055	int i;
2056	uint8_t pkt[8] = { 0 };
2057
2058	size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]);
2059
2060	RZ(rump_init());
2061
2062	for (i = 0; i < 3; i++) {
2063
2064		ATF_CHECK(prog_validate(insns[i], insn_count));
2065		ATF_CHECK(exec_prog(insns[i], insn_count, pkt, 8) == 0);
2066	}
2067}
2068
2069ATF_TC(bpfjit_ld_ind_x_overflow1);
2070ATF_TC_HEAD(bpfjit_ld_ind_x_overflow1, tc)
2071{
2072	atf_tc_set_md_var(tc, "descr",
2073	    "Test JIT compilation of BPF_LD+BPF_IND with overflow in X+4");
2074}
2075
2076ATF_TC_BODY(bpfjit_ld_ind_x_overflow1, tc)
2077{
2078	static struct bpf_insn insns[] = {
2079		BPF_STMT(BPF_LD+BPF_LEN, 0),
2080		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xffffffff)),
2081		BPF_STMT(BPF_MISC+BPF_TAX, 0),
2082		BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0),
2083		BPF_STMT(BPF_RET+BPF_A, 0)
2084	};
2085
2086	size_t i;
2087	bpfjit_func_t code;
2088	uint8_t pkt[8] = { 10, 20, 30, 40, 50, 60, 70, 80 };
2089
2090	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2091
2092	RZ(rump_init());
2093
2094	ATF_CHECK(prog_validate(insns, insn_count));
2095
2096	rump_schedule();
2097	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2098	rump_unschedule();
2099	ATF_REQUIRE(code != NULL);
2100
2101	for (i = 1; i <= sizeof(pkt); i++) {
2102		//ATF_CHECK(bpf_filter(insns, pkt, i, i) == 10 * i);
2103		ATF_CHECK(jitcall(code, pkt, i, i) == 10 * i);
2104	}
2105
2106	rump_schedule();
2107	rumpns_bpfjit_free_code(code);
2108	rump_unschedule();
2109}
2110
2111ATF_TC(bpfjit_ld_ind_x_overflow2);
2112ATF_TC_HEAD(bpfjit_ld_ind_x_overflow2, tc)
2113{
2114	atf_tc_set_md_var(tc, "descr",
2115	    "Test JIT compilation of BPF_LD+BPF_IND with overflow in X+4");
2116}
2117
2118ATF_TC_BODY(bpfjit_ld_ind_x_overflow2, tc)
2119{
2120	static struct bpf_insn insns[] = {
2121		BPF_STMT(BPF_LD+BPF_LEN, 0),
2122		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xffffffff)),
2123		BPF_STMT(BPF_ST, 3),
2124		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 3),
2125		BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0),
2126		BPF_STMT(BPF_RET+BPF_A, 0)
2127	};
2128
2129	size_t i;
2130	bpfjit_func_t code;
2131	uint8_t pkt[8] = { 10, 20, 30, 40, 50, 60, 70, 80 };
2132
2133	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2134
2135	RZ(rump_init());
2136
2137	ATF_CHECK(prog_validate(insns, insn_count));
2138
2139	rump_schedule();
2140	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2141	rump_unschedule();
2142	ATF_REQUIRE(code != NULL);
2143
2144	for (i = 1; i <= sizeof(pkt); i++) {
2145		//ATF_CHECK(bpf_filter(insns, pkt, i, i) == 10 * i);
2146		ATF_CHECK(jitcall(code, pkt, i, i) == 10 * i);
2147	}
2148
2149	rump_schedule();
2150	rumpns_bpfjit_free_code(code);
2151	rump_unschedule();
2152}
2153
2154ATF_TC(bpfjit_ld_len);
2155ATF_TC_HEAD(bpfjit_ld_len, tc)
2156{
2157	atf_tc_set_md_var(tc, "descr",
2158	    "Test JIT compilation of BPF_LD+BPF_W+BPF_LEN");
2159}
2160
2161ATF_TC_BODY(bpfjit_ld_len, tc)
2162{
2163	static struct bpf_insn insns[] = {
2164		BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
2165		BPF_STMT(BPF_RET+BPF_A, 0)
2166	};
2167
2168	size_t i;
2169	bpfjit_func_t code;
2170	uint8_t pkt[32]; /* the program doesn't read any data */
2171
2172	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2173
2174	RZ(rump_init());
2175
2176	ATF_CHECK(prog_validate(insns, insn_count));
2177
2178	rump_schedule();
2179	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2180	rump_unschedule();
2181	ATF_REQUIRE(code != NULL);
2182
2183	for (i = 0; i < sizeof(pkt); i++)
2184		ATF_CHECK(jitcall(code, pkt, i, 1) == i);
2185
2186	rump_schedule();
2187	rumpns_bpfjit_free_code(code);
2188	rump_unschedule();
2189}
2190
2191ATF_TC(bpfjit_ld_imm);
2192ATF_TC_HEAD(bpfjit_ld_imm, tc)
2193{
2194	atf_tc_set_md_var(tc, "descr",
2195	    "Test JIT compilation of BPF_LD+BPF_IMM");
2196}
2197
2198ATF_TC_BODY(bpfjit_ld_imm, tc)
2199{
2200	static struct bpf_insn insns[] = {
2201		BPF_STMT(BPF_LD+BPF_IMM, UINT32_MAX),
2202		BPF_STMT(BPF_RET+BPF_A, 0)
2203	};
2204
2205	uint8_t pkt[1]; /* the program doesn't read any data */
2206
2207	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2208
2209	RZ(rump_init());
2210
2211	ATF_CHECK(prog_validate(insns, insn_count));
2212	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX);
2213}
2214
2215ATF_TC(bpfjit_ldx_imm1);
2216ATF_TC_HEAD(bpfjit_ldx_imm1, tc)
2217{
2218	atf_tc_set_md_var(tc, "descr",
2219	    "Test JIT compilation of BPF_LDX+BPF_IMM");
2220}
2221
2222ATF_TC_BODY(bpfjit_ldx_imm1, tc)
2223{
2224	static struct bpf_insn insns[] = {
2225		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_MAX - 5),
2226		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2227		BPF_STMT(BPF_RET+BPF_A, 0)
2228	};
2229
2230	uint8_t pkt[1]; /* the program doesn't read any data */
2231
2232	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2233
2234	RZ(rump_init());
2235
2236	ATF_CHECK(prog_validate(insns, insn_count));
2237	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX - 5);
2238}
2239
2240ATF_TC(bpfjit_ldx_imm2);
2241ATF_TC_HEAD(bpfjit_ldx_imm2, tc)
2242{
2243	atf_tc_set_md_var(tc, "descr",
2244	    "Test JIT compilation of BPF_LDX+BPF_IMM");
2245}
2246
2247ATF_TC_BODY(bpfjit_ldx_imm2, tc)
2248{
2249	static struct bpf_insn insns[] = {
2250		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
2251		BPF_STMT(BPF_LD+BPF_IMM, 5),
2252		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
2253		BPF_STMT(BPF_RET+BPF_K, 7),
2254		BPF_STMT(BPF_RET+BPF_K, UINT32_MAX)
2255	};
2256
2257	uint8_t pkt[1]; /* the program doesn't read any data */
2258
2259	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2260
2261	RZ(rump_init());
2262
2263	ATF_CHECK(prog_validate(insns, insn_count));
2264	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX);
2265}
2266
2267ATF_TC(bpfjit_ldx_len1);
2268ATF_TC_HEAD(bpfjit_ldx_len1, tc)
2269{
2270	atf_tc_set_md_var(tc, "descr",
2271	    "Test JIT compilation of BPF_LDX+BPF_LEN");
2272}
2273
2274ATF_TC_BODY(bpfjit_ldx_len1, tc)
2275{
2276	static struct bpf_insn insns[] = {
2277		BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
2278		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2279		BPF_STMT(BPF_RET+BPF_A, 0)
2280	};
2281
2282	size_t i;
2283	bpfjit_func_t code;
2284	uint8_t pkt[5]; /* the program doesn't read any data */
2285
2286	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2287
2288	RZ(rump_init());
2289
2290	ATF_CHECK(prog_validate(insns, insn_count));
2291
2292	rump_schedule();
2293	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2294	rump_unschedule();
2295	ATF_REQUIRE(code != NULL);
2296
2297	for (i = 1; i < sizeof(pkt); i++) {
2298		ATF_CHECK(jitcall(code, pkt, i, 1) == i);
2299		ATF_CHECK(jitcall(code, pkt, i + 1, i) == i + 1);
2300	}
2301
2302	rump_schedule();
2303	rumpns_bpfjit_free_code(code);
2304	rump_unschedule();
2305}
2306
2307ATF_TC(bpfjit_ldx_len2);
2308ATF_TC_HEAD(bpfjit_ldx_len2, tc)
2309{
2310	atf_tc_set_md_var(tc, "descr",
2311	    "Test JIT compilation of BPF_LDX+BPF_LEN");
2312}
2313
2314ATF_TC_BODY(bpfjit_ldx_len2, tc)
2315{
2316	static struct bpf_insn insns[] = {
2317		BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
2318		BPF_STMT(BPF_LD+BPF_IMM, 5),
2319		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
2320		BPF_STMT(BPF_RET+BPF_K, 7),
2321		BPF_STMT(BPF_RET+BPF_K, UINT32_MAX)
2322	};
2323
2324	bpfjit_func_t code;
2325	uint8_t pkt[5]; /* the program doesn't read any data */
2326
2327	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2328
2329	RZ(rump_init());
2330
2331	ATF_CHECK(prog_validate(insns, insn_count));
2332
2333	rump_schedule();
2334	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2335	rump_unschedule();
2336	ATF_REQUIRE(code != NULL);
2337
2338	ATF_CHECK(jitcall(code, pkt, 5, 1) == UINT32_MAX);
2339	ATF_CHECK(jitcall(code, pkt, 6, 5) == 7);
2340
2341	rump_schedule();
2342	rumpns_bpfjit_free_code(code);
2343	rump_unschedule();
2344}
2345
2346ATF_TC(bpfjit_ldx_msh);
2347ATF_TC_HEAD(bpfjit_ldx_msh, tc)
2348{
2349	atf_tc_set_md_var(tc, "descr",
2350	    "Test JIT compilation of BPF_LDX+BPF_MSH");
2351}
2352
2353ATF_TC_BODY(bpfjit_ldx_msh, tc)
2354{
2355	static struct bpf_insn insns[] = {
2356		BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 1),
2357		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2358		BPF_STMT(BPF_RET+BPF_A, 0)
2359	};
2360
2361	uint8_t pkt[2] = { 0, 0x7a };
2362
2363	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2364
2365	RZ(rump_init());
2366
2367	ATF_CHECK(prog_validate(insns, insn_count));
2368	ATF_CHECK(exec_prog(insns, insn_count, pkt, 2) == 40);
2369}
2370
2371ATF_TC(bpfjit_misc_tax);
2372ATF_TC_HEAD(bpfjit_misc_tax, tc)
2373{
2374	atf_tc_set_md_var(tc, "descr",
2375	    "Test JIT compilation of BPF_MISC+BPF_TAX");
2376}
2377
2378ATF_TC_BODY(bpfjit_misc_tax, tc)
2379{
2380	static struct bpf_insn insns[] = {
2381		BPF_STMT(BPF_LD+BPF_IMM, 3),
2382		BPF_STMT(BPF_MISC+BPF_TAX, 0),
2383		BPF_STMT(BPF_LD+BPF_B+BPF_IND, 2),
2384		BPF_STMT(BPF_RET+BPF_A, 0)
2385	};
2386
2387	uint8_t pkt[6] = { 0, 11, 22, 33, 44, 55 };
2388
2389	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2390
2391	RZ(rump_init());
2392
2393	ATF_CHECK(prog_validate(insns, insn_count));
2394	ATF_CHECK(exec_prog(insns, insn_count, pkt, 6) == 55);
2395}
2396
2397ATF_TC(bpfjit_misc_txa);
2398ATF_TC_HEAD(bpfjit_misc_txa, tc)
2399{
2400	atf_tc_set_md_var(tc, "descr",
2401	    "Test JIT compilation of BPF_MISC+BPF_TXA");
2402}
2403
2404ATF_TC_BODY(bpfjit_misc_txa, tc)
2405{
2406	static struct bpf_insn insns[] = {
2407		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 391),
2408		BPF_STMT(BPF_MISC+BPF_TXA, 0),
2409		BPF_STMT(BPF_RET+BPF_A, 0)
2410	};
2411
2412	uint8_t pkt[1]; /* the program doesn't read any data */
2413
2414	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2415
2416	RZ(rump_init());
2417
2418	ATF_CHECK(prog_validate(insns, insn_count));
2419	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 391);
2420}
2421
2422ATF_TC(bpfjit_st1);
2423ATF_TC_HEAD(bpfjit_st1, tc)
2424{
2425	atf_tc_set_md_var(tc, "descr",
2426	    "Test JIT compilation of BPF_ST");
2427}
2428
2429ATF_TC_BODY(bpfjit_st1, tc)
2430{
2431	static struct bpf_insn insns[] = {
2432		BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
2433		BPF_STMT(BPF_ST, 0),
2434		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
2435		BPF_STMT(BPF_LD+BPF_MEM, 0),
2436		BPF_STMT(BPF_RET+BPF_A, 0)
2437	};
2438
2439	size_t i;
2440	bpfjit_func_t code;
2441	uint8_t pkt[16]; /* the program doesn't read any data */
2442
2443	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2444
2445	RZ(rump_init());
2446
2447	ATF_CHECK(prog_validate(insns, insn_count));
2448
2449	rump_schedule();
2450	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2451	rump_unschedule();
2452	ATF_REQUIRE(code != NULL);
2453
2454	for (i = 1; i <= sizeof(pkt); i++)
2455		ATF_CHECK(jitcall(code, pkt, i, sizeof(pkt)) == i);
2456
2457	rump_schedule();
2458	rumpns_bpfjit_free_code(code);
2459	rump_unschedule();
2460}
2461
2462ATF_TC(bpfjit_st2);
2463ATF_TC_HEAD(bpfjit_st2, tc)
2464{
2465	atf_tc_set_md_var(tc, "descr",
2466	    "Test JIT compilation of BPF_ST");
2467}
2468
2469ATF_TC_BODY(bpfjit_st2, tc)
2470{
2471	static struct bpf_insn insns[] = {
2472		BPF_STMT(BPF_ST, 0),
2473		BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
2474		BPF_STMT(BPF_ST, BPF_MEMWORDS-1),
2475		BPF_STMT(BPF_LD+BPF_MEM, 0),
2476		BPF_STMT(BPF_RET+BPF_A, 0)
2477	};
2478
2479	uint8_t pkt[1]; /* the program doesn't read any data */
2480
2481	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2482
2483	RZ(rump_init());
2484
2485	ATF_CHECK(prog_validate(insns, insn_count));
2486	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0);
2487}
2488
2489ATF_TC(bpfjit_st3);
2490ATF_TC_HEAD(bpfjit_st3, tc)
2491{
2492	atf_tc_set_md_var(tc, "descr",
2493	    "Test JIT compilation of BPF_ST");
2494}
2495
2496ATF_TC_BODY(bpfjit_st3, tc)
2497{
2498	static struct bpf_insn insns[] = {
2499		BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
2500		BPF_STMT(BPF_ST, 0),
2501		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 100),
2502		BPF_STMT(BPF_ST, BPF_MEMWORDS-1),
2503		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 200),
2504		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 301, 2, 0),
2505		BPF_STMT(BPF_LD+BPF_MEM, BPF_MEMWORDS-1),
2506		BPF_STMT(BPF_RET+BPF_A, 0),
2507		BPF_STMT(BPF_LD+BPF_MEM, 0),
2508		BPF_STMT(BPF_RET+BPF_A, 0)
2509	};
2510
2511	bpfjit_func_t code;
2512	uint8_t pkt[2]; /* the program doesn't read any data */
2513
2514	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2515
2516	ATF_REQUIRE(BPF_MEMWORDS > 1);
2517
2518	RZ(rump_init());
2519
2520	ATF_CHECK(prog_validate(insns, insn_count));
2521
2522	rump_schedule();
2523	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2524	rump_unschedule();
2525	ATF_REQUIRE(code != NULL);
2526
2527	ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
2528	ATF_CHECK(jitcall(code, pkt, 2, 2) == 102);
2529
2530	rump_schedule();
2531	rumpns_bpfjit_free_code(code);
2532	rump_unschedule();
2533}
2534
2535ATF_TC(bpfjit_st4);
2536ATF_TC_HEAD(bpfjit_st4, tc)
2537{
2538	atf_tc_set_md_var(tc, "descr",
2539	    "Test JIT compilation of BPF_ST");
2540}
2541
2542ATF_TC_BODY(bpfjit_st4, tc)
2543{
2544	static struct bpf_insn insns[] = {
2545		BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
2546		BPF_STMT(BPF_ST, 5),
2547		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 100),
2548		BPF_STMT(BPF_ST, BPF_MEMWORDS-1),
2549		BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 200),
2550		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 301, 2, 0),
2551		BPF_STMT(BPF_LD+BPF_MEM, BPF_MEMWORDS-1),
2552		BPF_STMT(BPF_RET+BPF_A, 0),
2553		BPF_STMT(BPF_LD+BPF_MEM, 5),
2554		BPF_STMT(BPF_RET+BPF_A, 0)
2555	};
2556
2557	bpfjit_func_t code;
2558	uint8_t pkt[2]; /* the program doesn't read any data */
2559
2560	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2561
2562	ATF_REQUIRE(BPF_MEMWORDS > 6);
2563
2564	RZ(rump_init());
2565
2566	ATF_CHECK(prog_validate(insns, insn_count));
2567
2568	rump_schedule();
2569	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2570	rump_unschedule();
2571	ATF_REQUIRE(code != NULL);
2572
2573	ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
2574	ATF_CHECK(jitcall(code, pkt, 2, 2) == 102);
2575
2576	rump_schedule();
2577	rumpns_bpfjit_free_code(code);
2578	rump_unschedule();
2579}
2580
2581ATF_TC(bpfjit_st5);
2582ATF_TC_HEAD(bpfjit_st5, tc)
2583{
2584	atf_tc_set_md_var(tc, "descr",
2585	    "Test JIT compilation of BPF_ST");
2586}
2587
2588ATF_TC_BODY(bpfjit_st5, tc)
2589{
2590	struct bpf_insn insns[5*BPF_MEMWORDS+2];
2591	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2592
2593	size_t k;
2594	bpfjit_func_t code;
2595	uint8_t pkt[BPF_MEMWORDS]; /* the program doesn't read any data */
2596
2597	memset(insns, 0, sizeof(insns));
2598
2599	/* for each k do M[k] = k */
2600	for (k = 0; k < BPF_MEMWORDS; k++) {
2601		insns[2*k].code   = BPF_LD+BPF_IMM;
2602		insns[2*k].k      = 3*k;
2603		insns[2*k+1].code = BPF_ST;
2604		insns[2*k+1].k    = k;
2605	}
2606
2607	/* load wirelen into A */
2608	insns[2*BPF_MEMWORDS].code = BPF_LD+BPF_W+BPF_LEN;
2609
2610	/* for each k, if (A == k + 1) return M[k] */
2611	for (k = 0; k < BPF_MEMWORDS; k++) {
2612		insns[2*BPF_MEMWORDS+3*k+1].code = BPF_JMP+BPF_JEQ+BPF_K;
2613		insns[2*BPF_MEMWORDS+3*k+1].k    = k+1;
2614		insns[2*BPF_MEMWORDS+3*k+1].jt   = 0;
2615		insns[2*BPF_MEMWORDS+3*k+1].jf   = 2;
2616		insns[2*BPF_MEMWORDS+3*k+2].code = BPF_LD+BPF_MEM;
2617		insns[2*BPF_MEMWORDS+3*k+2].k    = k;
2618		insns[2*BPF_MEMWORDS+3*k+3].code = BPF_RET+BPF_A;
2619		insns[2*BPF_MEMWORDS+3*k+3].k    = 0;
2620	}
2621
2622	insns[5*BPF_MEMWORDS+1].code = BPF_RET+BPF_K;
2623	insns[5*BPF_MEMWORDS+1].k    = UINT32_MAX;
2624
2625	RZ(rump_init());
2626
2627	ATF_CHECK(prog_validate(insns, insn_count));
2628
2629	rump_schedule();
2630	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2631	rump_unschedule();
2632	ATF_REQUIRE(code != NULL);
2633
2634	for (k = 1; k <= sizeof(pkt); k++)
2635		ATF_CHECK(jitcall(code, pkt, k, k) == 3*(k-1));
2636
2637	rump_schedule();
2638	rumpns_bpfjit_free_code(code);
2639	rump_unschedule();
2640}
2641
2642ATF_TC(bpfjit_stx1);
2643ATF_TC_HEAD(bpfjit_stx1, tc)
2644{
2645	atf_tc_set_md_var(tc, "descr",
2646	    "Test JIT compilation of BPF_STX");
2647}
2648
2649ATF_TC_BODY(bpfjit_stx1, tc)
2650{
2651	static struct bpf_insn insns[] = {
2652		BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
2653		BPF_STMT(BPF_STX, 0),
2654		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0),
2655		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2656		BPF_STMT(BPF_RET+BPF_A, 0)
2657	};
2658
2659	size_t i;
2660	bpfjit_func_t code;
2661	uint8_t pkt[16]; /* the program doesn't read any data */
2662
2663	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2664
2665	RZ(rump_init());
2666
2667	ATF_CHECK(prog_validate(insns, insn_count));
2668
2669	rump_schedule();
2670	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2671	rump_unschedule();
2672	ATF_REQUIRE(code != NULL);
2673
2674	for (i = 1; i <= sizeof(pkt); i++)
2675		ATF_CHECK(jitcall(code, pkt, i, sizeof(pkt)) == i);
2676
2677	rump_schedule();
2678	rumpns_bpfjit_free_code(code);
2679	rump_unschedule();
2680}
2681
2682ATF_TC(bpfjit_stx2);
2683ATF_TC_HEAD(bpfjit_stx2, tc)
2684{
2685	atf_tc_set_md_var(tc, "descr",
2686	    "Test JIT compilation of BPF_STX");
2687}
2688
2689ATF_TC_BODY(bpfjit_stx2, tc)
2690{
2691	static struct bpf_insn insns[] = {
2692		BPF_STMT(BPF_ST, 0),
2693		BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
2694		BPF_STMT(BPF_STX, BPF_MEMWORDS-1),
2695		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0),
2696		BPF_STMT(BPF_MISC+BPF_TXA, 0),
2697		BPF_STMT(BPF_RET+BPF_A, 0)
2698	};
2699
2700	uint8_t pkt[1]; /* the program doesn't read any data */
2701
2702	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2703
2704	RZ(rump_init());
2705
2706	ATF_CHECK(prog_validate(insns, insn_count));
2707	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0);
2708}
2709
2710ATF_TC(bpfjit_stx3);
2711ATF_TC_HEAD(bpfjit_stx3, tc)
2712{
2713	atf_tc_set_md_var(tc, "descr",
2714	    "Test JIT compilation of BPF_STX");
2715}
2716
2717ATF_TC_BODY(bpfjit_stx3, tc)
2718{
2719	static struct bpf_insn insns[] = {
2720		BPF_STMT(BPF_STX, 6),
2721		BPF_STMT(BPF_ST, 1),
2722		BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
2723		BPF_STMT(BPF_STX, 5),
2724		BPF_STMT(BPF_STX, 2),
2725		BPF_STMT(BPF_STX, 3),
2726		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 1),
2727		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2728		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 2),
2729		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2730		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 3),
2731		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2732		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 5),
2733		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2734		BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 6),
2735		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2736		BPF_STMT(BPF_RET+BPF_A, 0)
2737	};
2738
2739	size_t i;
2740	bpfjit_func_t code;
2741	uint8_t pkt[16]; /* the program doesn't read any data */
2742
2743	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2744
2745	RZ(rump_init());
2746
2747	ATF_CHECK(prog_validate(insns, insn_count));
2748
2749	rump_schedule();
2750	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2751	rump_unschedule();
2752	ATF_REQUIRE(code != NULL);
2753
2754	for (i = 1; i <= sizeof(pkt); i++)
2755		ATF_CHECK(jitcall(code, pkt, i, sizeof(pkt)) == 3 * i);
2756
2757	rump_schedule();
2758	rumpns_bpfjit_free_code(code);
2759	rump_unschedule();
2760}
2761
2762ATF_TC(bpfjit_stx4);
2763ATF_TC_HEAD(bpfjit_stx4, tc)
2764{
2765	atf_tc_set_md_var(tc, "descr",
2766	    "Test JIT compilation of BPF_STX");
2767}
2768
2769ATF_TC_BODY(bpfjit_stx4, tc)
2770{
2771	struct bpf_insn insns[5*BPF_MEMWORDS+2];
2772	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2773
2774	size_t k;
2775	bpfjit_func_t code;
2776	uint8_t pkt[BPF_MEMWORDS]; /* the program doesn't read any data */
2777
2778	memset(insns, 0, sizeof(insns));
2779
2780	/* for each k do M[k] = k */
2781	for (k = 0; k < BPF_MEMWORDS; k++) {
2782		insns[2*k].code   = BPF_LDX+BPF_W+BPF_IMM;
2783		insns[2*k].k      = 3*k;
2784		insns[2*k+1].code = BPF_STX;
2785		insns[2*k+1].k    = k;
2786	}
2787
2788	/* load wirelen into A */
2789	insns[2*BPF_MEMWORDS].code = BPF_LD+BPF_W+BPF_LEN;
2790
2791	/* for each k, if (A == k + 1) return M[k] */
2792	for (k = 0; k < BPF_MEMWORDS; k++) {
2793		insns[2*BPF_MEMWORDS+3*k+1].code = BPF_JMP+BPF_JEQ+BPF_K;
2794		insns[2*BPF_MEMWORDS+3*k+1].k    = k+1;
2795		insns[2*BPF_MEMWORDS+3*k+1].jt   = 0;
2796		insns[2*BPF_MEMWORDS+3*k+1].jf   = 2;
2797		insns[2*BPF_MEMWORDS+3*k+2].code = BPF_LD+BPF_MEM;
2798		insns[2*BPF_MEMWORDS+3*k+2].k    = k;
2799		insns[2*BPF_MEMWORDS+3*k+3].code = BPF_RET+BPF_A;
2800		insns[2*BPF_MEMWORDS+3*k+3].k    = 0;
2801	}
2802
2803	insns[5*BPF_MEMWORDS+1].code = BPF_RET+BPF_K;
2804	insns[5*BPF_MEMWORDS+1].k    = UINT32_MAX;
2805
2806	RZ(rump_init());
2807
2808	ATF_CHECK(prog_validate(insns, insn_count));
2809
2810	rump_schedule();
2811	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2812	rump_unschedule();
2813	ATF_REQUIRE(code != NULL);
2814
2815	for (k = 1; k <= sizeof(pkt); k++)
2816		ATF_CHECK(jitcall(code, pkt, k, k) == 3*(k-1));
2817
2818	rump_schedule();
2819	rumpns_bpfjit_free_code(code);
2820	rump_unschedule();
2821}
2822
2823ATF_TC(bpfjit_opt_ld_abs_1);
2824ATF_TC_HEAD(bpfjit_opt_ld_abs_1, tc)
2825{
2826	atf_tc_set_md_var(tc, "descr",
2827	    "Test JIT compilation with length optimization "
2828	    "applied to BPF_LD+BPF_ABS");
2829}
2830
2831ATF_TC_BODY(bpfjit_opt_ld_abs_1, tc)
2832{
2833	static struct bpf_insn insns[] = {
2834		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
2835		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 8),
2836		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
2837		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
2838		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
2839		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4),
2840		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3),
2841		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
2842		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1),
2843		BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
2844		BPF_STMT(BPF_RET+BPF_K, 0),
2845	};
2846
2847	size_t i, j;
2848	bpfjit_func_t code;
2849	uint8_t pkt[2][34] = {
2850		{
2851			0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
2852			14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
2853			0x80, 0x03, 0x70, 0x0f,
2854			0x80, 0x03, 0x70, 0x23
2855		},
2856		{
2857			0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
2858			14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
2859			0x80, 0x03, 0x70, 0x23,
2860			0x80, 0x03, 0x70, 0x0f
2861		}
2862	};
2863
2864	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2865
2866	RZ(rump_init());
2867
2868	ATF_CHECK(prog_validate(insns, insn_count));
2869
2870	rump_schedule();
2871	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2872	rump_unschedule();
2873	ATF_REQUIRE(code != NULL);
2874
2875	for (i = 0; i < 2; i++) {
2876		for (j = 1; j < sizeof(pkt[i]); j++)
2877			ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
2878		ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
2879	}
2880
2881	rump_schedule();
2882	rumpns_bpfjit_free_code(code);
2883	rump_unschedule();
2884}
2885
2886ATF_TC(bpfjit_opt_ld_abs_2);
2887ATF_TC_HEAD(bpfjit_opt_ld_abs_2, tc)
2888{
2889	atf_tc_set_md_var(tc, "descr",
2890	    "Test JIT compilation with length optimization "
2891	    "applied to BPF_LD+BPF_ABS");
2892}
2893
2894ATF_TC_BODY(bpfjit_opt_ld_abs_2, tc)
2895{
2896	static struct bpf_insn insns[] = {
2897		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
2898		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
2899		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
2900		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 6),
2901		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 5),
2902		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
2903		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 3),
2904		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
2905		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
2906		BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
2907		BPF_STMT(BPF_RET+BPF_K, 0),
2908	};
2909
2910	size_t i, j;
2911	bpfjit_func_t code;
2912	uint8_t pkt[2][34] = {
2913		{
2914			0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
2915			14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
2916			0x80, 0x03, 0x70, 0x0f,
2917			0x80, 0x03, 0x70, 0x23
2918		},
2919		{
2920			0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
2921			14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
2922			0x80, 0x03, 0x70, 0x23,
2923			0x80, 0x03, 0x70, 0x0f
2924		}
2925	};
2926
2927	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2928
2929	RZ(rump_init());
2930
2931	ATF_CHECK(prog_validate(insns, insn_count));
2932
2933	rump_schedule();
2934	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2935	rump_unschedule();
2936	ATF_REQUIRE(code != NULL);
2937
2938	for (i = 0; i < 2; i++) {
2939		for (j = 1; j < sizeof(pkt[i]); j++)
2940			ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
2941		ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
2942	}
2943
2944	rump_schedule();
2945	rumpns_bpfjit_free_code(code);
2946	rump_unschedule();
2947}
2948
2949ATF_TC(bpfjit_opt_ld_abs_3);
2950ATF_TC_HEAD(bpfjit_opt_ld_abs_3, tc)
2951{
2952	atf_tc_set_md_var(tc, "descr",
2953	    "Test JIT compilation with length optimization "
2954	    "applied to BPF_LD+BPF_ABS");
2955}
2956
2957ATF_TC_BODY(bpfjit_opt_ld_abs_3, tc)
2958{
2959	static struct bpf_insn insns[] = {
2960		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
2961		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2),
2962		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
2963		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 6),
2964		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 5),
2965		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
2966		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3),
2967		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
2968		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
2969		BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
2970		BPF_STMT(BPF_RET+BPF_K, 0),
2971	};
2972
2973	size_t i, j;
2974	bpfjit_func_t code;
2975	uint8_t pkt[2][34] = {
2976		{
2977			0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
2978			14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
2979			0x80, 0x03, 0x70, 0x0f,
2980			0x80, 0x03, 0x70, 0x23
2981		},
2982		{
2983			0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
2984			14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
2985			0x80, 0x03, 0x70, 0x23,
2986			0x80, 0x03, 0x70, 0x0f
2987		}
2988	};
2989
2990	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2991
2992	RZ(rump_init());
2993
2994	ATF_CHECK(prog_validate(insns, insn_count));
2995
2996	rump_schedule();
2997	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2998	rump_unschedule();
2999	ATF_REQUIRE(code != NULL);
3000
3001	for (i = 0; i < 2; i++) {
3002		for (j = 1; j < sizeof(pkt[i]); j++)
3003			ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
3004		ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
3005	}
3006
3007	rump_schedule();
3008	rumpns_bpfjit_free_code(code);
3009	rump_unschedule();
3010}
3011
3012ATF_TC(bpfjit_opt_ld_ind_1);
3013ATF_TC_HEAD(bpfjit_opt_ld_ind_1, tc)
3014{
3015	atf_tc_set_md_var(tc, "descr",
3016	    "Test JIT compilation with length optimization "
3017	    "applied to BPF_LD+BPF_IND");
3018}
3019
3020ATF_TC_BODY(bpfjit_opt_ld_ind_1, tc)
3021{
3022	static struct bpf_insn insns[] = {
3023		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 12),
3024		BPF_STMT(BPF_LD+BPF_H+BPF_IND, 0),
3025		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 8),
3026		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 14),
3027		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
3028		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 18),
3029		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4),
3030		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3),
3031		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 18),
3032		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1),
3033		BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3034		BPF_STMT(BPF_RET+BPF_K, 0),
3035	};
3036
3037	size_t i, j;
3038	bpfjit_func_t code;
3039	uint8_t pkt[2][34] = {
3040		{
3041			0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3042			14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3043			0x80, 0x03, 0x70, 0x0f,
3044			0x80, 0x03, 0x70, 0x23
3045		},
3046		{
3047			0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3048			14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3049			0x80, 0x03, 0x70, 0x23,
3050			0x80, 0x03, 0x70, 0x0f
3051		}
3052	};
3053
3054	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3055
3056	RZ(rump_init());
3057
3058	ATF_CHECK(prog_validate(insns, insn_count));
3059
3060	rump_schedule();
3061	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3062	rump_unschedule();
3063	ATF_REQUIRE(code != NULL);
3064
3065	for (i = 0; i < 2; i++) {
3066		for (j = 1; j < sizeof(pkt[i]); j++)
3067			ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
3068		ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
3069	}
3070
3071	rump_schedule();
3072	rumpns_bpfjit_free_code(code);
3073	rump_unschedule();
3074}
3075
3076ATF_TC(bpfjit_opt_ld_ind_2);
3077ATF_TC_HEAD(bpfjit_opt_ld_ind_2, tc)
3078{
3079	atf_tc_set_md_var(tc, "descr",
3080	    "Test JIT compilation with length optimization "
3081	    "applied to BPF_LD+BPF_IND");
3082}
3083
3084ATF_TC_BODY(bpfjit_opt_ld_ind_2, tc)
3085{
3086	static struct bpf_insn insns[] = {
3087		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
3088		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 26),
3089		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
3090		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 30),
3091		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 6),
3092		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 5),
3093		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 30),
3094		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 3),
3095		BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12),
3096		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
3097		BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3098		BPF_STMT(BPF_RET+BPF_K, 0),
3099	};
3100
3101	size_t i, j;
3102	bpfjit_func_t code;
3103	uint8_t pkt[2][34] = {
3104		{
3105			0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3106			14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3107			0x80, 0x03, 0x70, 0x0f,
3108			0x80, 0x03, 0x70, 0x23
3109		},
3110		{
3111			0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3112			14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3113			0x80, 0x03, 0x70, 0x23,
3114			0x80, 0x03, 0x70, 0x0f
3115		}
3116	};
3117
3118	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3119
3120	RZ(rump_init());
3121
3122	ATF_CHECK(prog_validate(insns, insn_count));
3123
3124	rump_schedule();
3125	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3126	rump_unschedule();
3127	ATF_REQUIRE(code != NULL);
3128
3129	for (i = 0; i < 2; i++) {
3130		for (j = 1; j < sizeof(pkt[i]); j++)
3131			ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
3132		ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
3133	}
3134
3135	rump_schedule();
3136	rumpns_bpfjit_free_code(code);
3137	rump_unschedule();
3138}
3139
3140ATF_TC(bpfjit_opt_ld_ind_3);
3141ATF_TC_HEAD(bpfjit_opt_ld_ind_3, tc)
3142{
3143	atf_tc_set_md_var(tc, "descr",
3144	    "Test JIT compilation with length optimization "
3145	    "applied to BPF_LD+BPF_IND");
3146}
3147
3148ATF_TC_BODY(bpfjit_opt_ld_ind_3, tc)
3149{
3150	static struct bpf_insn insns[] = {
3151		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 15),
3152		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15),
3153		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2),
3154		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 11),
3155		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 7),
3156		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 6),
3157		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 11),
3158		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 4),
3159		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
3160		BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12),
3161		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
3162		BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3163		BPF_STMT(BPF_RET+BPF_K, 0),
3164	};
3165
3166	size_t i, j;
3167	bpfjit_func_t code;
3168	uint8_t pkt[2][34] = {
3169		{
3170			0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3171			14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3172			0x80, 0x03, 0x70, 0x0f,
3173			0x80, 0x03, 0x70, 0x23
3174		},
3175		{
3176			0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3177			14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3178			0x80, 0x03, 0x70, 0x23,
3179			0x80, 0x03, 0x70, 0x0f
3180		}
3181	};
3182
3183	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3184
3185	RZ(rump_init());
3186
3187	ATF_CHECK(prog_validate(insns, insn_count));
3188
3189	rump_schedule();
3190	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3191	rump_unschedule();
3192	ATF_REQUIRE(code != NULL);
3193
3194	for (i = 0; i < 2; i++) {
3195		for (j = 1; j < sizeof(pkt[i]); j++)
3196			ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
3197		ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
3198	}
3199
3200	rump_schedule();
3201	rumpns_bpfjit_free_code(code);
3202	rump_unschedule();
3203}
3204
3205ATF_TC(bpfjit_opt_ld_ind_4);
3206ATF_TC_HEAD(bpfjit_opt_ld_ind_4, tc)
3207{
3208	atf_tc_set_md_var(tc, "descr",
3209	    "Test JIT compilation with length optimization "
3210	    "applied to BPF_LD+BPF_IND");
3211}
3212
3213ATF_TC_BODY(bpfjit_opt_ld_ind_4, tc)
3214{
3215	static struct bpf_insn insns[] = {
3216		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 11),
3217		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 19),
3218		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2),
3219		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15),
3220		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 7),
3221		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 6),
3222		BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15),
3223		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 4),
3224		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
3225		BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12),
3226		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
3227		BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3228		BPF_STMT(BPF_RET+BPF_K, 0),
3229	};
3230
3231	size_t i, j;
3232	bpfjit_func_t code;
3233	uint8_t pkt[2][34] = {
3234		{
3235			0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3236			14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3237			0x80, 0x03, 0x70, 0x0f,
3238			0x80, 0x03, 0x70, 0x23
3239		},
3240		{
3241			0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3242			14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3243			0x80, 0x03, 0x70, 0x23,
3244			0x80, 0x03, 0x70, 0x0f
3245		}
3246	};
3247
3248	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3249
3250	RZ(rump_init());
3251
3252	ATF_CHECK(prog_validate(insns, insn_count));
3253
3254	rump_schedule();
3255	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3256	rump_unschedule();
3257	ATF_REQUIRE(code != NULL);
3258
3259	for (i = 0; i < 2; i++) {
3260		for (j = 1; j < sizeof(pkt[i]); j++)
3261			ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
3262		ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
3263	}
3264
3265	rump_schedule();
3266	rumpns_bpfjit_free_code(code);
3267	rump_unschedule();
3268}
3269
3270ATF_TC(bpfjit_abc_ja);
3271ATF_TC_HEAD(bpfjit_abc_ja, tc)
3272{
3273	atf_tc_set_md_var(tc, "descr",
3274	    "Test ABC optimization with a single BPF_JMP+BPF_JA");
3275}
3276
3277ATF_TC_BODY(bpfjit_abc_ja, tc)
3278{
3279	static struct bpf_insn insns[] = {
3280		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3), /* min. length 4 */
3281		BPF_STMT(BPF_JMP+BPF_JA, 2),
3282		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, UINT32_MAX - 1),
3283		BPF_STMT(BPF_RET+BPF_K, 0),
3284		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 2), /* min. length 6 */
3285		BPF_STMT(BPF_RET+BPF_A, 0),
3286		BPF_STMT(BPF_RET+BPF_K, 1),
3287		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 6),
3288		BPF_STMT(BPF_RET+BPF_K, 2),
3289		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
3290		BPF_STMT(BPF_RET+BPF_K, 3),
3291	};
3292
3293	bpfjit_func_t code;
3294	uint8_t pkt[6] = {0, 0, /* UINT32_MAX: */ 255, 255, 255, 255};
3295
3296	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3297
3298	RZ(rump_init());
3299
3300	ATF_CHECK(prog_validate(insns, insn_count));
3301
3302	rump_schedule();
3303	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3304	rump_unschedule();
3305	ATF_REQUIRE(code != NULL);
3306
3307	ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
3308	ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
3309	ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
3310	ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
3311	ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
3312	ATF_CHECK(jitcall(code, pkt, 6, 6) == UINT32_MAX);
3313
3314	rump_schedule();
3315	rumpns_bpfjit_free_code(code);
3316	rump_unschedule();
3317}
3318
3319ATF_TC(bpfjit_abc_ja_over);
3320ATF_TC_HEAD(bpfjit_abc_ja_over, tc)
3321{
3322	atf_tc_set_md_var(tc, "descr",
3323	    "Test ABC optimization when BPF_JMP+BPF_JA jumps over all loads");
3324}
3325
3326ATF_TC_BODY(bpfjit_abc_ja_over, tc)
3327{
3328	static struct bpf_insn insns[] = {
3329		BPF_STMT(BPF_JMP+BPF_JA, 2),
3330		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3),
3331		BPF_STMT(BPF_RET+BPF_K, 0),
3332		BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3333		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 4),
3334		BPF_STMT(BPF_RET+BPF_K, 1),
3335		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 5),
3336		BPF_STMT(BPF_RET+BPF_K, 2),
3337		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 6),
3338		BPF_STMT(BPF_RET+BPF_K, 3),
3339	};
3340
3341	uint8_t pkt[1]; /* the program doesn't read any data */
3342
3343	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3344
3345	RZ(rump_init());
3346
3347	ATF_CHECK(prog_validate(insns, insn_count));
3348	ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX);
3349}
3350
3351ATF_TC(bpfjit_abc_ld_chain);
3352ATF_TC_HEAD(bpfjit_abc_ld_chain, tc)
3353{
3354	atf_tc_set_md_var(tc, "descr",
3355	    "Test ABC optimization of a chain of BPF_LD instructions "
3356	    "with exits leading to a single BPF_RET");
3357}
3358
3359ATF_TC_BODY(bpfjit_abc_ld_chain, tc)
3360{
3361	static struct bpf_insn insns[] = {
3362		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3), /* min. length 4 */
3363		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 8, 0, 4),
3364		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 4), /* min. length 6 */
3365		BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 7, 0, 2),
3366		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 6), /* min. length 10 */
3367		BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 6, 0, 1),
3368		BPF_STMT(BPF_RET+BPF_K, 123456789),
3369		BPF_STMT(BPF_RET+BPF_K, 987654321),
3370	};
3371
3372	bpfjit_func_t code;
3373	uint8_t pkt[10] = {};
3374
3375	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3376
3377	RZ(rump_init());
3378
3379	ATF_CHECK(prog_validate(insns, insn_count));
3380
3381	rump_schedule();
3382	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3383	rump_unschedule();
3384	ATF_REQUIRE(code != NULL);
3385
3386	/* Packet is too short. */
3387	ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
3388	ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
3389	ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
3390
3391	/* !(pkt[3] == 8) => return 123456789 */
3392	ATF_CHECK(jitcall(code, pkt, 4, 4) == 123456789);
3393	ATF_CHECK(jitcall(code, pkt, 5, 5) == 123456789);
3394	ATF_CHECK(jitcall(code, pkt, 6, 6) == 123456789);
3395	ATF_CHECK(jitcall(code, pkt, 7, 7) == 123456789);
3396	ATF_CHECK(jitcall(code, pkt, 8, 8) == 123456789);
3397	ATF_CHECK(jitcall(code, pkt, 9, 9) == 123456789);
3398
3399	/* !(pkt[4:2] >= 7) => too short or return 123456789 */
3400	pkt[3] = 8;
3401	ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
3402	ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
3403	ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
3404	ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
3405	ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
3406	ATF_CHECK(jitcall(code, pkt, 6, 6) == 123456789);
3407	ATF_CHECK(jitcall(code, pkt, 9, 9) == 123456789);
3408
3409	/* !(pkt[6:4] > 6) => too short or return 987654321 */
3410	pkt[4] = pkt[5] = 1;
3411	ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
3412	ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
3413	ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
3414	ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
3415	ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
3416	ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
3417	ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
3418	ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
3419	ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
3420	ATF_CHECK(jitcall(code, pkt, 10, 10) == 987654321);
3421
3422	/* (pkt[6:4] > 6) => too short or return 123456789 */
3423	pkt[6] = pkt[7] = pkt[8] = pkt[9] = 1;
3424	ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
3425	ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
3426	ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
3427	ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
3428	ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
3429	ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
3430	ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
3431	ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
3432	ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
3433	ATF_CHECK(jitcall(code, pkt, 10, 10) == 123456789);
3434
3435	rump_schedule();
3436	rumpns_bpfjit_free_code(code);
3437	rump_unschedule();
3438}
3439
3440ATF_TC(bpfjit_examples_1);
3441ATF_TC_HEAD(bpfjit_examples_1, tc)
3442{
3443	atf_tc_set_md_var(tc, "descr",
3444	    "Test the first example from bpf(4) - "
3445	    "accept Reverse ARP requests");
3446}
3447
3448ATF_TC_BODY(bpfjit_examples_1, tc)
3449{
3450	/*
3451	 * The following filter is taken from the Reverse ARP
3452	 * Daemon. It accepts only Reverse ARP requests.
3453	 */
3454	struct bpf_insn insns[] = {
3455		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
3456		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8035, 0, 3),
3457		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20),
3458		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 3, 0, 1),
3459		BPF_STMT(BPF_RET+BPF_K, 42),
3460		BPF_STMT(BPF_RET+BPF_K, 0),
3461	};
3462
3463	bpfjit_func_t code;
3464	uint8_t pkt[22] = {};
3465
3466	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3467
3468	RZ(rump_init());
3469
3470	ATF_CHECK(prog_validate(insns, insn_count));
3471
3472	rump_schedule();
3473	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3474	rump_unschedule();
3475	ATF_REQUIRE(code != NULL);
3476
3477	/* Packet is too short. */
3478	ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
3479	ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
3480	ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
3481	ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
3482	ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
3483	ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
3484	ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
3485	ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
3486	ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
3487	ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
3488	ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
3489	ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
3490	ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
3491	ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
3492	ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
3493	ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
3494	ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
3495	ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
3496	ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
3497	ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
3498	ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
3499
3500	/* The packet doesn't match. */
3501	ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
3502
3503	/* Still no match after setting the protocol field. */
3504	pkt[12] = 0x80; pkt[13] = 0x35;
3505	ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
3506
3507	/* Set RARP message type. */
3508	pkt[21] = 3;
3509	ATF_CHECK(jitcall(code, pkt, 22, 22) == 42);
3510
3511	/* Packet is too short. */
3512	ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
3513	ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
3514	ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
3515	ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
3516	ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
3517	ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
3518	ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
3519	ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
3520	ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
3521	ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
3522	ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
3523	ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
3524	ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
3525	ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
3526	ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
3527	ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
3528	ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
3529	ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
3530	ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
3531	ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
3532	ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
3533
3534	/* Change RARP message type. */
3535	pkt[20] = 3;
3536	ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
3537
3538	rump_schedule();
3539	rumpns_bpfjit_free_code(code);
3540	rump_unschedule();
3541}
3542
3543ATF_TC(bpfjit_examples_2);
3544ATF_TC_HEAD(bpfjit_examples_2, tc)
3545{
3546	atf_tc_set_md_var(tc, "descr",
3547	    "Test the second example from bpf(4) - "
3548	    "accept IP packets between two specified hosts");
3549}
3550
3551ATF_TC_BODY(bpfjit_examples_2, tc)
3552{
3553	/*
3554	 * This filter accepts only IP packets between host 128.3.112.15
3555	 * and 128.3.112.35.
3556	 */
3557	static struct bpf_insn insns[] = {
3558		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
3559		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x0800, 0, 8),
3560		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
3561		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
3562		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
3563		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4),
3564		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3),
3565		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
3566		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1),
3567		BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3568		BPF_STMT(BPF_RET+BPF_K, 0),
3569	};
3570
3571	bpfjit_func_t code;
3572	uint8_t pkt[34] = {};
3573
3574	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3575
3576	RZ(rump_init());
3577
3578	ATF_CHECK(prog_validate(insns, insn_count));
3579
3580	rump_schedule();
3581	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3582	rump_unschedule();
3583	ATF_REQUIRE(code != NULL);
3584
3585	/* Packet is too short. */
3586	ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
3587	ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
3588	ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
3589	ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
3590	ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
3591	ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
3592	ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
3593	ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
3594	ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
3595	ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
3596	ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
3597	ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
3598	ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
3599	ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
3600	ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
3601	ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
3602	ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
3603	ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
3604	ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
3605	ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
3606	ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
3607	ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
3608	ATF_CHECK(jitcall(code, pkt, 23, 23) == 0);
3609	ATF_CHECK(jitcall(code, pkt, 24, 24) == 0);
3610	ATF_CHECK(jitcall(code, pkt, 25, 25) == 0);
3611	ATF_CHECK(jitcall(code, pkt, 26, 26) == 0);
3612	ATF_CHECK(jitcall(code, pkt, 27, 27) == 0);
3613	ATF_CHECK(jitcall(code, pkt, 28, 28) == 0);
3614	ATF_CHECK(jitcall(code, pkt, 29, 29) == 0);
3615	ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
3616	ATF_CHECK(jitcall(code, pkt, 31, 31) == 0);
3617	ATF_CHECK(jitcall(code, pkt, 32, 32) == 0);
3618	ATF_CHECK(jitcall(code, pkt, 33, 33) == 0);
3619
3620	/* The packet doesn't match. */
3621	ATF_CHECK(jitcall(code, pkt, 34, 34) == 0);
3622
3623	/* Still no match after setting the protocol field. */
3624	pkt[12] = 8;
3625	ATF_CHECK(jitcall(code, pkt, 34, 34) == 0);
3626
3627	pkt[26] = 128; pkt[27] = 3; pkt[28] = 112; pkt[29] = 15;
3628	ATF_CHECK(jitcall(code, pkt, 34, 34) == 0);
3629
3630	pkt[30] = 128; pkt[31] = 3; pkt[32] = 112; pkt[33] = 35;
3631	ATF_CHECK(jitcall(code, pkt, 34, 34) == UINT32_MAX);
3632
3633	/* Swap the ip addresses. */
3634	pkt[26] = 128; pkt[27] = 3; pkt[28] = 112; pkt[29] = 35;
3635	ATF_CHECK(jitcall(code, pkt, 34, 34) == 0);
3636
3637	pkt[30] = 128; pkt[31] = 3; pkt[32] = 112; pkt[33] = 15;
3638	ATF_CHECK(jitcall(code, pkt, 34, 34) == UINT32_MAX);
3639
3640	/* Packet is too short. */
3641	ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
3642	ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
3643	ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
3644	ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
3645	ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
3646	ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
3647	ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
3648	ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
3649	ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
3650	ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
3651	ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
3652	ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
3653	ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
3654	ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
3655	ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
3656	ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
3657	ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
3658	ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
3659	ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
3660	ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
3661	ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
3662	ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
3663	ATF_CHECK(jitcall(code, pkt, 23, 23) == 0);
3664	ATF_CHECK(jitcall(code, pkt, 24, 24) == 0);
3665	ATF_CHECK(jitcall(code, pkt, 25, 25) == 0);
3666	ATF_CHECK(jitcall(code, pkt, 26, 26) == 0);
3667	ATF_CHECK(jitcall(code, pkt, 27, 27) == 0);
3668	ATF_CHECK(jitcall(code, pkt, 28, 28) == 0);
3669	ATF_CHECK(jitcall(code, pkt, 29, 29) == 0);
3670	ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
3671	ATF_CHECK(jitcall(code, pkt, 31, 31) == 0);
3672	ATF_CHECK(jitcall(code, pkt, 32, 32) == 0);
3673	ATF_CHECK(jitcall(code, pkt, 33, 33) == 0);
3674
3675	/* Change the protocol field. */
3676	pkt[13] = 8;
3677	ATF_CHECK(jitcall(code, pkt, 34, 34) == 0);
3678
3679	rump_schedule();
3680	rumpns_bpfjit_free_code(code);
3681	rump_unschedule();
3682}
3683
3684ATF_TC(bpfjit_examples_3);
3685ATF_TC_HEAD(bpfjit_examples_3, tc)
3686{
3687	atf_tc_set_md_var(tc, "descr",
3688	    "Test the third example from bpf(4) - "
3689	    "accept TCP finger packets");
3690}
3691
3692ATF_TC_BODY(bpfjit_examples_3, tc)
3693{
3694	/*
3695	 * This filter returns only TCP finger packets.
3696	 */
3697	struct bpf_insn insns[] = {
3698		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
3699		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x0800, 0, 10),
3700		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 23),
3701		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 6, 0, 8),
3702		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20),
3703		BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 0x1fff, 6, 0),
3704		BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 14),
3705		BPF_STMT(BPF_LD+BPF_H+BPF_IND, 14),
3706		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 2, 0),
3707		BPF_STMT(BPF_LD+BPF_H+BPF_IND, 16),
3708		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 0, 1),
3709		BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3710		BPF_STMT(BPF_RET+BPF_K, 0),
3711	};
3712
3713	bpfjit_func_t code;
3714	uint8_t pkt[30] = {};
3715
3716	/* Set IP fragment offset to non-zero. */
3717	pkt[20] = 1; pkt[21] = 1;
3718
3719	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3720
3721	RZ(rump_init());
3722
3723	ATF_CHECK(prog_validate(insns, insn_count));
3724
3725	rump_schedule();
3726	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3727	rump_unschedule();
3728	ATF_REQUIRE(code != NULL);
3729
3730	/* Packet is too short. */
3731	ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
3732	ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
3733	ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
3734	ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
3735	ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
3736	ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
3737	ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
3738	ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
3739	ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
3740	ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
3741	ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
3742	ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
3743	ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
3744	ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
3745	ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
3746	ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
3747	ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
3748	ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
3749	ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
3750	ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
3751	ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
3752	ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
3753	ATF_CHECK(jitcall(code, pkt, 23, 23) == 0);
3754	ATF_CHECK(jitcall(code, pkt, 24, 24) == 0);
3755	ATF_CHECK(jitcall(code, pkt, 25, 25) == 0);
3756	ATF_CHECK(jitcall(code, pkt, 26, 26) == 0);
3757	ATF_CHECK(jitcall(code, pkt, 27, 27) == 0);
3758	ATF_CHECK(jitcall(code, pkt, 28, 28) == 0);
3759	ATF_CHECK(jitcall(code, pkt, 29, 29) == 0);
3760
3761	/* The packet doesn't match. */
3762	ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
3763
3764	/* Still no match after setting the protocol field. */
3765	pkt[12] = 8;
3766	ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
3767
3768	/* Get one step closer to the match. */
3769	pkt[23] = 6;
3770	ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
3771
3772	/* Set IP fragment offset to zero. */
3773	pkt[20] = 0x20; pkt[21] = 0;
3774	ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
3775
3776	/* Set IP header length to 12. */
3777	pkt[14] = 0xd3;
3778	ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
3779
3780	/* Match one branch of the program. */
3781	pkt[27] = 79;
3782	ATF_CHECK(jitcall(code, pkt, 30, 30) == UINT32_MAX);
3783
3784	/* Match the other branch of the program. */
3785	pkt[29] = 79; pkt[27] = 0;
3786	ATF_CHECK(jitcall(code, pkt, 30, 30) == UINT32_MAX);
3787
3788	/* Packet is too short. */
3789	ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
3790	ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
3791	ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
3792	ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
3793	ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
3794	ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
3795	ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
3796	ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
3797	ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
3798	ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
3799	ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
3800	ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
3801	ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
3802	ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
3803	ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
3804	ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
3805	ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
3806	ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
3807	ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
3808	ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
3809	ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
3810	ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
3811	ATF_CHECK(jitcall(code, pkt, 23, 23) == 0);
3812	ATF_CHECK(jitcall(code, pkt, 24, 24) == 0);
3813	ATF_CHECK(jitcall(code, pkt, 25, 25) == 0);
3814	ATF_CHECK(jitcall(code, pkt, 26, 26) == 0);
3815	ATF_CHECK(jitcall(code, pkt, 27, 27) == 0);
3816	ATF_CHECK(jitcall(code, pkt, 28, 28) == 0);
3817	ATF_CHECK(jitcall(code, pkt, 29, 29) == 0);
3818
3819	/* Set IP header length to 16. Packet is too short. */
3820	pkt[14] = 4;
3821	ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
3822
3823	rump_schedule();
3824	rumpns_bpfjit_free_code(code);
3825	rump_unschedule();
3826}
3827
3828ATF_TC(bpfjit_cop_no_ctx);
3829ATF_TC_HEAD(bpfjit_cop_no_ctx, tc)
3830{
3831	atf_tc_set_md_var(tc, "descr", "Test that BPF_MISC|BPF_COP "
3832	    "instruction can't be accepted without a context");
3833}
3834
3835ATF_TC_BODY(bpfjit_cop_no_ctx, tc)
3836{
3837	static struct bpf_insn insns[] = {
3838		BPF_STMT(BPF_MISC+BPF_COP, 0),
3839		BPF_STMT(BPF_RET+BPF_K, 7)
3840	};
3841
3842	bpfjit_func_t code;
3843	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3844
3845	RZ(rump_init());
3846
3847	ATF_CHECK(!prog_validate(insns, insn_count));
3848
3849	rump_schedule();
3850	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3851	rump_unschedule();
3852	ATF_CHECK(code == NULL);
3853}
3854
3855ATF_TC(bpfjit_copx_no_ctx);
3856ATF_TC_HEAD(bpfjit_copx_no_ctx, tc)
3857{
3858	atf_tc_set_md_var(tc, "descr", "Test that BPF_MISC|BPF_COPX "
3859	    "instruction can't be accepted without a context");
3860}
3861
3862ATF_TC_BODY(bpfjit_copx_no_ctx, tc)
3863{
3864	static struct bpf_insn insns[] = {
3865		BPF_STMT(BPF_MISC+BPF_COPX, 0),
3866		BPF_STMT(BPF_RET+BPF_K, 7)
3867	};
3868
3869	bpfjit_func_t code;
3870	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3871
3872	RZ(rump_init());
3873
3874	ATF_CHECK(!prog_validate(insns, insn_count));
3875
3876	rump_schedule();
3877	code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3878	rump_unschedule();
3879	ATF_CHECK(code == NULL);
3880}
3881
3882ATF_TP_ADD_TCS(tp)
3883{
3884
3885	/*
3886	 * For every new test please also add a similar test
3887	 * to ../../lib/libbpfjit/t_bpfjit.c
3888	 */
3889	ATF_TP_ADD_TC(tp, bpfjit_empty);
3890	ATF_TP_ADD_TC(tp, bpfjit_alu_add_k);
3891	ATF_TP_ADD_TC(tp, bpfjit_alu_sub_k);
3892	ATF_TP_ADD_TC(tp, bpfjit_alu_mul_k);
3893	ATF_TP_ADD_TC(tp, bpfjit_alu_div0_k);
3894	ATF_TP_ADD_TC(tp, bpfjit_alu_div1_k);
3895	ATF_TP_ADD_TC(tp, bpfjit_alu_div2_k);
3896	ATF_TP_ADD_TC(tp, bpfjit_alu_div4_k);
3897	ATF_TP_ADD_TC(tp, bpfjit_alu_div10_k);
3898	ATF_TP_ADD_TC(tp, bpfjit_alu_div10000_k);
3899	ATF_TP_ADD_TC(tp, bpfjit_alu_div7609801_k);
3900	ATF_TP_ADD_TC(tp, bpfjit_alu_div80000000_k);
3901	ATF_TP_ADD_TC(tp, bpfjit_alu_and_k);
3902	ATF_TP_ADD_TC(tp, bpfjit_alu_or_k);
3903	ATF_TP_ADD_TC(tp, bpfjit_alu_lsh_k);
3904	ATF_TP_ADD_TC(tp, bpfjit_alu_lsh0_k);
3905	ATF_TP_ADD_TC(tp, bpfjit_alu_rsh_k);
3906	ATF_TP_ADD_TC(tp, bpfjit_alu_rsh0_k);
3907	ATF_TP_ADD_TC(tp, bpfjit_alu_modulo_k);
3908	ATF_TP_ADD_TC(tp, bpfjit_alu_add_x);
3909	ATF_TP_ADD_TC(tp, bpfjit_alu_sub_x);
3910	ATF_TP_ADD_TC(tp, bpfjit_alu_mul_x);
3911	ATF_TP_ADD_TC(tp, bpfjit_alu_div0_x);
3912	ATF_TP_ADD_TC(tp, bpfjit_alu_div1_x);
3913	ATF_TP_ADD_TC(tp, bpfjit_alu_div2_x);
3914	ATF_TP_ADD_TC(tp, bpfjit_alu_div4_x);
3915	ATF_TP_ADD_TC(tp, bpfjit_alu_div10_x);
3916	ATF_TP_ADD_TC(tp, bpfjit_alu_div10000_x);
3917	ATF_TP_ADD_TC(tp, bpfjit_alu_div7609801_x);
3918	ATF_TP_ADD_TC(tp, bpfjit_alu_div80000000_x);
3919	ATF_TP_ADD_TC(tp, bpfjit_alu_and_x);
3920	ATF_TP_ADD_TC(tp, bpfjit_alu_or_x);
3921	ATF_TP_ADD_TC(tp, bpfjit_alu_lsh_x);
3922	ATF_TP_ADD_TC(tp, bpfjit_alu_lsh0_x);
3923	ATF_TP_ADD_TC(tp, bpfjit_alu_rsh_x);
3924	ATF_TP_ADD_TC(tp, bpfjit_alu_rsh0_x);
3925	ATF_TP_ADD_TC(tp, bpfjit_alu_modulo_x);
3926	ATF_TP_ADD_TC(tp, bpfjit_alu_neg);
3927	ATF_TP_ADD_TC(tp, bpfjit_jmp_ja);
3928	ATF_TP_ADD_TC(tp, bpfjit_jmp_jgt_k);
3929	ATF_TP_ADD_TC(tp, bpfjit_jmp_jge_k);
3930	ATF_TP_ADD_TC(tp, bpfjit_jmp_jeq_k);
3931	ATF_TP_ADD_TC(tp, bpfjit_jmp_jset_k);
3932	ATF_TP_ADD_TC(tp, bpfjit_jmp_modulo_k);
3933	ATF_TP_ADD_TC(tp, bpfjit_jmp_jgt_x);
3934	ATF_TP_ADD_TC(tp, bpfjit_jmp_jge_x);
3935	ATF_TP_ADD_TC(tp, bpfjit_jmp_jeq_x);
3936	ATF_TP_ADD_TC(tp, bpfjit_jmp_jset_x);
3937	ATF_TP_ADD_TC(tp, bpfjit_jmp_modulo_x);
3938	ATF_TP_ADD_TC(tp, bpfjit_ld_abs);
3939	ATF_TP_ADD_TC(tp, bpfjit_ld_abs_k_overflow);
3940	ATF_TP_ADD_TC(tp, bpfjit_ld_ind);
3941	ATF_TP_ADD_TC(tp, bpfjit_ld_ind_k_overflow);
3942	ATF_TP_ADD_TC(tp, bpfjit_ld_ind_x_overflow1);
3943	ATF_TP_ADD_TC(tp, bpfjit_ld_ind_x_overflow2);
3944	ATF_TP_ADD_TC(tp, bpfjit_ld_len);
3945	ATF_TP_ADD_TC(tp, bpfjit_ld_imm);
3946	ATF_TP_ADD_TC(tp, bpfjit_ldx_imm1);
3947	ATF_TP_ADD_TC(tp, bpfjit_ldx_imm2);
3948	ATF_TP_ADD_TC(tp, bpfjit_ldx_len1);
3949	ATF_TP_ADD_TC(tp, bpfjit_ldx_len2);
3950	ATF_TP_ADD_TC(tp, bpfjit_ldx_msh);
3951	ATF_TP_ADD_TC(tp, bpfjit_misc_tax);
3952	ATF_TP_ADD_TC(tp, bpfjit_misc_txa);
3953	ATF_TP_ADD_TC(tp, bpfjit_st1);
3954	ATF_TP_ADD_TC(tp, bpfjit_st2);
3955	ATF_TP_ADD_TC(tp, bpfjit_st3);
3956	ATF_TP_ADD_TC(tp, bpfjit_st4);
3957	ATF_TP_ADD_TC(tp, bpfjit_st5);
3958	ATF_TP_ADD_TC(tp, bpfjit_stx1);
3959	ATF_TP_ADD_TC(tp, bpfjit_stx2);
3960	ATF_TP_ADD_TC(tp, bpfjit_stx3);
3961	ATF_TP_ADD_TC(tp, bpfjit_stx4);
3962	ATF_TP_ADD_TC(tp, bpfjit_opt_ld_abs_1);
3963	ATF_TP_ADD_TC(tp, bpfjit_opt_ld_abs_2);
3964	ATF_TP_ADD_TC(tp, bpfjit_opt_ld_abs_3);
3965	ATF_TP_ADD_TC(tp, bpfjit_opt_ld_ind_1);
3966	ATF_TP_ADD_TC(tp, bpfjit_opt_ld_ind_2);
3967	ATF_TP_ADD_TC(tp, bpfjit_opt_ld_ind_3);
3968	ATF_TP_ADD_TC(tp, bpfjit_opt_ld_ind_4);
3969	ATF_TP_ADD_TC(tp, bpfjit_abc_ja);
3970	ATF_TP_ADD_TC(tp, bpfjit_abc_ja_over);
3971	ATF_TP_ADD_TC(tp, bpfjit_abc_ld_chain);
3972	ATF_TP_ADD_TC(tp, bpfjit_examples_1);
3973	ATF_TP_ADD_TC(tp, bpfjit_examples_2);
3974	ATF_TP_ADD_TC(tp, bpfjit_examples_3);
3975	ATF_TP_ADD_TC(tp, bpfjit_cop_no_ctx);
3976	ATF_TP_ADD_TC(tp, bpfjit_copx_no_ctx);
3977
3978	return atf_no_error();
3979}
3980