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