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