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