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