t_bpfjit.c revision 1.10 1 /* $NetBSD: t_bpfjit.c,v 1.10 2015/02/14 20:25:08 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.10 2015/02/14 20:25:08 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, 1),
2153 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
2154 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 2, 0),
2155 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9),
2156 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 1),
2157 BPF_STMT(BPF_RET+BPF_K, 2),
2158 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
2159 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1),
2160 BPF_STMT(BPF_RET+BPF_K, 3),
2161 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7),
2162 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 2, 3),
2163 BPF_STMT(BPF_RET+BPF_K, 4),
2164 BPF_STMT(BPF_RET+BPF_K, 5),
2165 BPF_STMT(BPF_RET+BPF_K, 6),
2166 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6),
2167 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 3, 1),
2168 BPF_STMT(BPF_RET+BPF_K, 7),
2169 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
2170 BPF_STMT(BPF_RET+BPF_K, 8),
2171 BPF_STMT(BPF_RET+BPF_K, 9)
2172 };
2173
2174 bpfjit_func_t code;
2175 uint8_t pkt[8]; /* the program doesn't read any data */
2176
2177 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2178
2179 RZ(rump_init());
2180
2181 ATF_CHECK(prog_validate(insns, insn_count));
2182
2183 rump_schedule();
2184 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2185 rump_unschedule();
2186 ATF_REQUIRE(code != NULL);
2187
2188 ATF_CHECK(jitcall(code, pkt, 1, 1) == 8);
2189 ATF_CHECK(jitcall(code, pkt, 2, 2) == 8);
2190 ATF_CHECK(jitcall(code, pkt, 3, 3) == 2);
2191 ATF_CHECK(jitcall(code, pkt, 4, 4) == 8);
2192 ATF_CHECK(jitcall(code, pkt, 5, 5) == 3);
2193 ATF_CHECK(jitcall(code, pkt, 6, 6) == 9);
2194 ATF_CHECK(jitcall(code, pkt, 7, 7) == 6);
2195 ATF_CHECK(jitcall(code, pkt, 8, 8) == 1);
2196
2197 rump_schedule();
2198 rumpns_bpfjit_free_code(code);
2199 rump_unschedule();
2200 }
2201
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_jeq_x_noinit_ax);
2266 ATF_TC_HEAD(bpfjit_jmp_jeq_x_noinit_ax, tc)
2267 {
2268 atf_tc_set_md_var(tc, "descr", "Test JIT compilation "
2269 "of BPF_JMP+BPF_EQ+BPF_X with uninitialised A and X");
2270 }
2271
2272 ATF_TC_BODY(bpfjit_jmp_jeq_x_noinit_ax, tc)
2273 {
2274 static struct bpf_insn insns[] = {
2275 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1),
2276 BPF_STMT(BPF_RET+BPF_K, 10),
2277 BPF_STMT(BPF_RET+BPF_K, 11)
2278 };
2279
2280 bpfjit_func_t code;
2281 uint8_t pkt[8]; /* the program doesn't read any data */
2282
2283 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2284
2285 RZ(rump_init());
2286
2287 ATF_CHECK(prog_validate(insns, insn_count));
2288
2289 rump_schedule();
2290 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2291 rump_unschedule();
2292 ATF_REQUIRE(code != NULL);
2293
2294 ATF_CHECK(jitcall(code, pkt, 1, 1) == 10);
2295
2296 rump_schedule();
2297 rumpns_bpfjit_free_code(code);
2298 rump_unschedule();
2299 }
2300
2301 ATF_TC(bpfjit_jmp_modulo_x);
2302 ATF_TC_HEAD(bpfjit_jmp_modulo_x, tc)
2303 {
2304 atf_tc_set_md_var(tc, "descr",
2305 "Test JIT compilation of modulo logic of BPF_JMP+BPF_X operations");
2306 }
2307
2308 ATF_TC_BODY(bpfjit_jmp_modulo_x, tc)
2309 {
2310 static struct bpf_insn insns[] = {
2311 BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)),
2312 /* FFFFF770 << 4 = FFFFF770 */
2313 BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 4),
2314
2315 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff770)),
2316 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
2317 BPF_STMT(BPF_RET+BPF_K, 0),
2318 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1),
2319 BPF_STMT(BPF_RET+BPF_K, 1),
2320 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff771)),
2321 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1),
2322 BPF_STMT(BPF_RET+BPF_K, 2),
2323 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff770)),
2324 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 4),
2325 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0),
2326 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff771)),
2327 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 0),
2328 BPF_STMT(BPF_JMP+BPF_JA, 1),
2329 BPF_STMT(BPF_RET+BPF_K, 3),
2330
2331 /* FFFFF770+FFFFF770 = 00000001,FFFFEEE0 */
2332 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xfffff770)),
2333
2334 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee0)),
2335 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
2336 BPF_STMT(BPF_RET+BPF_K, 4),
2337 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1),
2338 BPF_STMT(BPF_RET+BPF_K, 5),
2339 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee1)),
2340 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1),
2341 BPF_STMT(BPF_RET+BPF_K, 6),
2342 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee0)),
2343 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 4),
2344 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0),
2345 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee1)),
2346 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 0),
2347 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
2348 BPF_STMT(BPF_RET+BPF_K, 7)
2349 };
2350
2351 uint8_t pkt[1]; /* the program doesn't read any data */
2352
2353 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2354
2355 RZ(rump_init());
2356
2357 ATF_CHECK(prog_validate(insns, insn_count));
2358 ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX);
2359 }
2360
2361 ATF_TC(bpfjit_ld_abs);
2362 ATF_TC_HEAD(bpfjit_ld_abs, tc)
2363 {
2364 atf_tc_set_md_var(tc, "descr",
2365 "Test JIT compilation of BPF_LD+BPF_ABS");
2366 }
2367
2368 ATF_TC_BODY(bpfjit_ld_abs, tc)
2369 {
2370 static struct bpf_insn insns[3][2] = {
2371 {
2372 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 5),
2373 BPF_STMT(BPF_RET+BPF_A, 0)
2374 },
2375 {
2376 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 5),
2377 BPF_STMT(BPF_RET+BPF_A, 0)
2378 },
2379 {
2380 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 5),
2381 BPF_STMT(BPF_RET+BPF_A, 0)
2382 }
2383 };
2384
2385 static size_t lengths[3] = { 1, 2, 4 };
2386 static unsigned int expected[3] = { 0xde, 0xdead, 0xdeadbeef };
2387
2388 size_t i, l;
2389 uint8_t *pkt = deadbeef_at_5;
2390 size_t pktsize = sizeof(deadbeef_at_5);
2391
2392 size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]);
2393
2394 RZ(rump_init());
2395
2396 for (i = 0; i < 3; i++) {
2397 bpfjit_func_t code;
2398
2399 ATF_CHECK(prog_validate(insns[i], insn_count));
2400
2401 rump_schedule();
2402 code = rumpns_bpfjit_generate_code(NULL, insns[i], insn_count);
2403 rump_unschedule();
2404 ATF_REQUIRE(code != NULL);
2405
2406 for (l = 1; l < 5 + lengths[i]; l++) {
2407 ATF_CHECK(jitcall(code, pkt, l, l) == 0);
2408 ATF_CHECK(jitcall(code, pkt, pktsize, l) == 0);
2409 }
2410
2411 l = 5 + lengths[i];
2412 ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]);
2413 ATF_CHECK(jitcall(code, pkt, pktsize, l) == expected[i]);
2414
2415 l = pktsize;
2416 ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]);
2417
2418 rump_schedule();
2419 rumpns_bpfjit_free_code(code);
2420 rump_unschedule();
2421 }
2422 }
2423
2424 ATF_TC(bpfjit_ld_abs_k_overflow);
2425 ATF_TC_HEAD(bpfjit_ld_abs_k_overflow, tc)
2426 {
2427 atf_tc_set_md_var(tc, "descr",
2428 "Test JIT compilation of BPF_LD+BPF_ABS with overflow in k+4");
2429 }
2430
2431 ATF_TC_BODY(bpfjit_ld_abs_k_overflow, tc)
2432 {
2433 static struct bpf_insn insns[12][3] = {
2434 {
2435 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX),
2436 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2437 BPF_STMT(BPF_RET+BPF_K, 1)
2438 },
2439 {
2440 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX - 1),
2441 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2442 BPF_STMT(BPF_RET+BPF_K, 1)
2443 },
2444 {
2445 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX),
2446 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2447 BPF_STMT(BPF_RET+BPF_K, 1)
2448 },
2449 {
2450 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 1),
2451 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2452 BPF_STMT(BPF_RET+BPF_K, 1)
2453 },
2454 {
2455 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 2),
2456 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2457 BPF_STMT(BPF_RET+BPF_K, 1)
2458 },
2459 {
2460 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 3),
2461 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2462 BPF_STMT(BPF_RET+BPF_K, 1)
2463 },
2464 {
2465 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2466 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX),
2467 BPF_STMT(BPF_RET+BPF_K, 1)
2468 },
2469 {
2470 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2471 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX - 1),
2472 BPF_STMT(BPF_RET+BPF_K, 1)
2473 },
2474 {
2475 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2476 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX),
2477 BPF_STMT(BPF_RET+BPF_K, 1)
2478 },
2479 {
2480 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2481 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 1),
2482 BPF_STMT(BPF_RET+BPF_K, 1)
2483 },
2484 {
2485 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2486 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 2),
2487 BPF_STMT(BPF_RET+BPF_K, 1)
2488 },
2489 {
2490 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
2491 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 3),
2492 BPF_STMT(BPF_RET+BPF_K, 1)
2493 }
2494 };
2495
2496 int i;
2497 uint8_t pkt[8] = { 0 };
2498
2499 size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]);
2500
2501 RZ(rump_init());
2502
2503 for (i = 0; i < 3; i++) {
2504 ATF_CHECK(prog_validate(insns[i], insn_count));
2505 ATF_CHECK(exec_prog(insns[i], insn_count, pkt, 8) == 0);
2506 }
2507 }
2508
2509 ATF_TC(bpfjit_ld_ind);
2510 ATF_TC_HEAD(bpfjit_ld_ind, tc)
2511 {
2512 atf_tc_set_md_var(tc, "descr",
2513 "Test JIT compilation of BPF_LD+BPF_IND");
2514 }
2515
2516 ATF_TC_BODY(bpfjit_ld_ind, tc)
2517 {
2518 static struct bpf_insn insns[6][3] = {
2519 {
2520 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
2521 BPF_STMT(BPF_LD+BPF_B+BPF_IND, 2),
2522 BPF_STMT(BPF_RET+BPF_A, 0)
2523 },
2524 {
2525 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
2526 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 2),
2527 BPF_STMT(BPF_RET+BPF_A, 0)
2528 },
2529 {
2530 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
2531 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 2),
2532 BPF_STMT(BPF_RET+BPF_A, 0)
2533 },
2534 {
2535 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
2536 BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0),
2537 BPF_STMT(BPF_RET+BPF_A, 0)
2538 },
2539 {
2540 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
2541 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 0),
2542 BPF_STMT(BPF_RET+BPF_A, 0)
2543 },
2544 {
2545 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
2546 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 0),
2547 BPF_STMT(BPF_RET+BPF_A, 0)
2548 }
2549 };
2550
2551 static size_t lengths[6] = { 1, 2, 4, 1, 2, 4 };
2552
2553 static unsigned int expected[6] = {
2554 0xde, 0xdead, 0xdeadbeef,
2555 0xde, 0xdead, 0xdeadbeef
2556 };
2557
2558 size_t i, l;
2559 uint8_t *pkt = deadbeef_at_5;
2560 size_t pktsize = sizeof(deadbeef_at_5);
2561
2562 size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]);
2563
2564 RZ(rump_init());
2565
2566 for (i = 0; i < 3; i++) {
2567 bpfjit_func_t code;
2568
2569 ATF_CHECK(prog_validate(insns[i], insn_count));
2570
2571 rump_schedule();
2572 code = rumpns_bpfjit_generate_code(NULL, insns[i], insn_count);
2573 rump_unschedule();
2574 ATF_REQUIRE(code != NULL);
2575
2576 for (l = 1; l < 5 + lengths[i]; l++) {
2577 ATF_CHECK(jitcall(code, pkt, l, l) == 0);
2578 ATF_CHECK(jitcall(code, pkt, pktsize, l) == 0);
2579 }
2580
2581 l = 5 + lengths[i];
2582 ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]);
2583 ATF_CHECK(jitcall(code, pkt, pktsize, l) == expected[i]);
2584
2585 l = pktsize;
2586 ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]);
2587
2588 rump_schedule();
2589 rumpns_bpfjit_free_code(code);
2590 rump_unschedule();
2591 }
2592 }
2593
2594 ATF_TC(bpfjit_ld_ind_k_overflow);
2595 ATF_TC_HEAD(bpfjit_ld_ind_k_overflow, tc)
2596 {
2597 atf_tc_set_md_var(tc, "descr",
2598 "Test JIT compilation of BPF_LD+BPF_IND with overflow in k+4");
2599 }
2600
2601 ATF_TC_BODY(bpfjit_ld_ind_k_overflow, tc)
2602 {
2603 static struct bpf_insn insns[12][3] = {
2604 {
2605 BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX),
2606 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2607 BPF_STMT(BPF_RET+BPF_K, 1)
2608 },
2609 {
2610 BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX - 1),
2611 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2612 BPF_STMT(BPF_RET+BPF_K, 1)
2613 },
2614 {
2615 BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX),
2616 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2617 BPF_STMT(BPF_RET+BPF_K, 1)
2618 },
2619 {
2620 BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 1),
2621 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2622 BPF_STMT(BPF_RET+BPF_K, 1)
2623 },
2624 {
2625 BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 2),
2626 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2627 BPF_STMT(BPF_RET+BPF_K, 1)
2628 },
2629 {
2630 BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 3),
2631 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2632 BPF_STMT(BPF_RET+BPF_K, 1)
2633 },
2634 {
2635 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2636 BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX),
2637 BPF_STMT(BPF_RET+BPF_K, 1)
2638 },
2639 {
2640 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2641 BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX - 1),
2642 BPF_STMT(BPF_RET+BPF_K, 1)
2643 },
2644 {
2645 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2646 BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX),
2647 BPF_STMT(BPF_RET+BPF_K, 1)
2648 },
2649 {
2650 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2651 BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 1),
2652 BPF_STMT(BPF_RET+BPF_K, 1)
2653 },
2654 {
2655 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2656 BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 2),
2657 BPF_STMT(BPF_RET+BPF_K, 1)
2658 },
2659 {
2660 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
2661 BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 3),
2662 BPF_STMT(BPF_RET+BPF_K, 1)
2663 }
2664 };
2665
2666 int i;
2667 uint8_t pkt[8] = { 0 };
2668
2669 size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]);
2670
2671 RZ(rump_init());
2672
2673 for (i = 0; i < 3; i++) {
2674
2675 ATF_CHECK(prog_validate(insns[i], insn_count));
2676 ATF_CHECK(exec_prog(insns[i], insn_count, pkt, 8) == 0);
2677 }
2678 }
2679
2680 ATF_TC(bpfjit_ld_ind_x_overflow1);
2681 ATF_TC_HEAD(bpfjit_ld_ind_x_overflow1, tc)
2682 {
2683 atf_tc_set_md_var(tc, "descr",
2684 "Test JIT compilation of BPF_LD+BPF_IND with overflow in X+4");
2685 }
2686
2687 ATF_TC_BODY(bpfjit_ld_ind_x_overflow1, tc)
2688 {
2689 static struct bpf_insn insns[] = {
2690 BPF_STMT(BPF_LD+BPF_LEN, 0),
2691 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xffffffff)),
2692 BPF_STMT(BPF_MISC+BPF_TAX, 0),
2693 BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0),
2694 BPF_STMT(BPF_RET+BPF_A, 0)
2695 };
2696
2697 size_t i;
2698 bpfjit_func_t code;
2699 uint8_t pkt[8] = { 10, 20, 30, 40, 50, 60, 70, 80 };
2700
2701 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2702
2703 RZ(rump_init());
2704
2705 ATF_CHECK(prog_validate(insns, insn_count));
2706
2707 rump_schedule();
2708 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2709 rump_unschedule();
2710 ATF_REQUIRE(code != NULL);
2711
2712 for (i = 1; i <= sizeof(pkt); i++) {
2713 //ATF_CHECK(bpf_filter(insns, pkt, i, i) == 10 * i);
2714 ATF_CHECK(jitcall(code, pkt, i, i) == 10 * i);
2715 }
2716
2717 rump_schedule();
2718 rumpns_bpfjit_free_code(code);
2719 rump_unschedule();
2720 }
2721
2722 ATF_TC(bpfjit_ld_ind_x_overflow2);
2723 ATF_TC_HEAD(bpfjit_ld_ind_x_overflow2, tc)
2724 {
2725 atf_tc_set_md_var(tc, "descr",
2726 "Test JIT compilation of BPF_LD+BPF_IND with overflow in X+4");
2727 }
2728
2729 ATF_TC_BODY(bpfjit_ld_ind_x_overflow2, tc)
2730 {
2731 static struct bpf_insn insns[] = {
2732 BPF_STMT(BPF_LD+BPF_LEN, 0),
2733 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xffffffff)),
2734 BPF_STMT(BPF_ST, 3),
2735 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 3),
2736 BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0),
2737 BPF_STMT(BPF_RET+BPF_A, 0)
2738 };
2739
2740 size_t i;
2741 bpfjit_func_t code;
2742 uint8_t pkt[8] = { 10, 20, 30, 40, 50, 60, 70, 80 };
2743
2744 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2745
2746 RZ(rump_init());
2747
2748 ATF_CHECK(prog_validate(insns, insn_count));
2749
2750 rump_schedule();
2751 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2752 rump_unschedule();
2753 ATF_REQUIRE(code != NULL);
2754
2755 for (i = 1; i <= sizeof(pkt); i++) {
2756 //ATF_CHECK(bpf_filter(insns, pkt, i, i) == 10 * i);
2757 ATF_CHECK(jitcall(code, pkt, i, i) == 10 * i);
2758 }
2759
2760 rump_schedule();
2761 rumpns_bpfjit_free_code(code);
2762 rump_unschedule();
2763 }
2764
2765 ATF_TC(bpfjit_ld_len);
2766 ATF_TC_HEAD(bpfjit_ld_len, tc)
2767 {
2768 atf_tc_set_md_var(tc, "descr",
2769 "Test JIT compilation of BPF_LD+BPF_W+BPF_LEN");
2770 }
2771
2772 ATF_TC_BODY(bpfjit_ld_len, tc)
2773 {
2774 static struct bpf_insn insns[] = {
2775 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
2776 BPF_STMT(BPF_RET+BPF_A, 0)
2777 };
2778
2779 size_t i;
2780 bpfjit_func_t code;
2781 uint8_t pkt[32]; /* the program doesn't read any data */
2782
2783 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2784
2785 RZ(rump_init());
2786
2787 ATF_CHECK(prog_validate(insns, insn_count));
2788
2789 rump_schedule();
2790 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2791 rump_unschedule();
2792 ATF_REQUIRE(code != NULL);
2793
2794 for (i = 0; i < sizeof(pkt); i++)
2795 ATF_CHECK(jitcall(code, pkt, i, 1) == i);
2796
2797 rump_schedule();
2798 rumpns_bpfjit_free_code(code);
2799 rump_unschedule();
2800 }
2801
2802 ATF_TC(bpfjit_ld_imm);
2803 ATF_TC_HEAD(bpfjit_ld_imm, tc)
2804 {
2805 atf_tc_set_md_var(tc, "descr",
2806 "Test JIT compilation of BPF_LD+BPF_IMM");
2807 }
2808
2809 ATF_TC_BODY(bpfjit_ld_imm, tc)
2810 {
2811 static struct bpf_insn insns[] = {
2812 BPF_STMT(BPF_LD+BPF_IMM, UINT32_MAX),
2813 BPF_STMT(BPF_RET+BPF_A, 0)
2814 };
2815
2816 uint8_t pkt[1]; /* the program doesn't read any data */
2817
2818 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2819
2820 RZ(rump_init());
2821
2822 ATF_CHECK(prog_validate(insns, insn_count));
2823 ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX);
2824 }
2825
2826 ATF_TC(bpfjit_ldx_imm1);
2827 ATF_TC_HEAD(bpfjit_ldx_imm1, tc)
2828 {
2829 atf_tc_set_md_var(tc, "descr",
2830 "Test JIT compilation of BPF_LDX+BPF_IMM");
2831 }
2832
2833 ATF_TC_BODY(bpfjit_ldx_imm1, tc)
2834 {
2835 static struct bpf_insn insns[] = {
2836 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_MAX - 5),
2837 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2838 BPF_STMT(BPF_RET+BPF_A, 0)
2839 };
2840
2841 uint8_t pkt[1]; /* the program doesn't read any data */
2842
2843 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2844
2845 RZ(rump_init());
2846
2847 ATF_CHECK(prog_validate(insns, insn_count));
2848 ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX - 5);
2849 }
2850
2851 ATF_TC(bpfjit_ldx_imm2);
2852 ATF_TC_HEAD(bpfjit_ldx_imm2, tc)
2853 {
2854 atf_tc_set_md_var(tc, "descr",
2855 "Test JIT compilation of BPF_LDX+BPF_IMM");
2856 }
2857
2858 ATF_TC_BODY(bpfjit_ldx_imm2, tc)
2859 {
2860 static struct bpf_insn insns[] = {
2861 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
2862 BPF_STMT(BPF_LD+BPF_IMM, 5),
2863 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
2864 BPF_STMT(BPF_RET+BPF_K, 7),
2865 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX)
2866 };
2867
2868 uint8_t pkt[1]; /* the program doesn't read any data */
2869
2870 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2871
2872 RZ(rump_init());
2873
2874 ATF_CHECK(prog_validate(insns, insn_count));
2875 ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX);
2876 }
2877
2878 ATF_TC(bpfjit_ldx_len1);
2879 ATF_TC_HEAD(bpfjit_ldx_len1, tc)
2880 {
2881 atf_tc_set_md_var(tc, "descr",
2882 "Test JIT compilation of BPF_LDX+BPF_LEN");
2883 }
2884
2885 ATF_TC_BODY(bpfjit_ldx_len1, tc)
2886 {
2887 static struct bpf_insn insns[] = {
2888 BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
2889 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2890 BPF_STMT(BPF_RET+BPF_A, 0)
2891 };
2892
2893 size_t i;
2894 bpfjit_func_t code;
2895 uint8_t pkt[5]; /* the program doesn't read any data */
2896
2897 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2898
2899 RZ(rump_init());
2900
2901 ATF_CHECK(prog_validate(insns, insn_count));
2902
2903 rump_schedule();
2904 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2905 rump_unschedule();
2906 ATF_REQUIRE(code != NULL);
2907
2908 for (i = 1; i < sizeof(pkt); i++) {
2909 ATF_CHECK(jitcall(code, pkt, i, 1) == i);
2910 ATF_CHECK(jitcall(code, pkt, i + 1, i) == i + 1);
2911 }
2912
2913 rump_schedule();
2914 rumpns_bpfjit_free_code(code);
2915 rump_unschedule();
2916 }
2917
2918 ATF_TC(bpfjit_ldx_len2);
2919 ATF_TC_HEAD(bpfjit_ldx_len2, tc)
2920 {
2921 atf_tc_set_md_var(tc, "descr",
2922 "Test JIT compilation of BPF_LDX+BPF_LEN");
2923 }
2924
2925 ATF_TC_BODY(bpfjit_ldx_len2, tc)
2926 {
2927 static struct bpf_insn insns[] = {
2928 BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
2929 BPF_STMT(BPF_LD+BPF_IMM, 5),
2930 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
2931 BPF_STMT(BPF_RET+BPF_K, 7),
2932 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX)
2933 };
2934
2935 bpfjit_func_t code;
2936 uint8_t pkt[5]; /* the program doesn't read any data */
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
2944 rump_schedule();
2945 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
2946 rump_unschedule();
2947 ATF_REQUIRE(code != NULL);
2948
2949 ATF_CHECK(jitcall(code, pkt, 5, 1) == UINT32_MAX);
2950 ATF_CHECK(jitcall(code, pkt, 6, 5) == 7);
2951
2952 rump_schedule();
2953 rumpns_bpfjit_free_code(code);
2954 rump_unschedule();
2955 }
2956
2957 ATF_TC(bpfjit_ldx_msh);
2958 ATF_TC_HEAD(bpfjit_ldx_msh, tc)
2959 {
2960 atf_tc_set_md_var(tc, "descr",
2961 "Test JIT compilation of BPF_LDX+BPF_MSH");
2962 }
2963
2964 ATF_TC_BODY(bpfjit_ldx_msh, tc)
2965 {
2966 static struct bpf_insn insns[] = {
2967 BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 1),
2968 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
2969 BPF_STMT(BPF_RET+BPF_A, 0)
2970 };
2971
2972 uint8_t pkt[2] = { 0, 0x7a };
2973
2974 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
2975
2976 RZ(rump_init());
2977
2978 ATF_CHECK(prog_validate(insns, insn_count));
2979 ATF_CHECK(exec_prog(insns, insn_count, pkt, 2) == 40);
2980 }
2981
2982 ATF_TC(bpfjit_misc_tax);
2983 ATF_TC_HEAD(bpfjit_misc_tax, tc)
2984 {
2985 atf_tc_set_md_var(tc, "descr",
2986 "Test JIT compilation of BPF_MISC+BPF_TAX");
2987 }
2988
2989 ATF_TC_BODY(bpfjit_misc_tax, tc)
2990 {
2991 static struct bpf_insn insns[] = {
2992 BPF_STMT(BPF_LD+BPF_IMM, 3),
2993 BPF_STMT(BPF_MISC+BPF_TAX, 0),
2994 BPF_STMT(BPF_LD+BPF_B+BPF_IND, 2),
2995 BPF_STMT(BPF_RET+BPF_A, 0)
2996 };
2997
2998 uint8_t pkt[6] = { 0, 11, 22, 33, 44, 55 };
2999
3000 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3001
3002 RZ(rump_init());
3003
3004 ATF_CHECK(prog_validate(insns, insn_count));
3005 ATF_CHECK(exec_prog(insns, insn_count, pkt, 6) == 55);
3006 }
3007
3008 ATF_TC(bpfjit_misc_txa);
3009 ATF_TC_HEAD(bpfjit_misc_txa, tc)
3010 {
3011 atf_tc_set_md_var(tc, "descr",
3012 "Test JIT compilation of BPF_MISC+BPF_TXA");
3013 }
3014
3015 ATF_TC_BODY(bpfjit_misc_txa, tc)
3016 {
3017 static struct bpf_insn insns[] = {
3018 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 391),
3019 BPF_STMT(BPF_MISC+BPF_TXA, 0),
3020 BPF_STMT(BPF_RET+BPF_A, 0)
3021 };
3022
3023 uint8_t pkt[1]; /* the program doesn't read any data */
3024
3025 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3026
3027 RZ(rump_init());
3028
3029 ATF_CHECK(prog_validate(insns, insn_count));
3030 ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 391);
3031 }
3032
3033 ATF_TC(bpfjit_st1);
3034 ATF_TC_HEAD(bpfjit_st1, tc)
3035 {
3036 atf_tc_set_md_var(tc, "descr",
3037 "Test JIT compilation of BPF_ST");
3038 }
3039
3040 ATF_TC_BODY(bpfjit_st1, tc)
3041 {
3042 static struct bpf_insn insns[] = {
3043 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
3044 BPF_STMT(BPF_ST, 0),
3045 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
3046 BPF_STMT(BPF_LD+BPF_MEM, 0),
3047 BPF_STMT(BPF_RET+BPF_A, 0)
3048 };
3049
3050 size_t i;
3051 bpfjit_func_t code;
3052 uint8_t pkt[16]; /* the program doesn't read any data */
3053
3054 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3055
3056 RZ(rump_init());
3057
3058 ATF_CHECK(prog_validate(insns, insn_count));
3059
3060 rump_schedule();
3061 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3062 rump_unschedule();
3063 ATF_REQUIRE(code != NULL);
3064
3065 for (i = 1; i <= sizeof(pkt); i++)
3066 ATF_CHECK(jitcall(code, pkt, i, sizeof(pkt)) == i);
3067
3068 rump_schedule();
3069 rumpns_bpfjit_free_code(code);
3070 rump_unschedule();
3071 }
3072
3073 ATF_TC(bpfjit_st2);
3074 ATF_TC_HEAD(bpfjit_st2, tc)
3075 {
3076 atf_tc_set_md_var(tc, "descr",
3077 "Test JIT compilation of BPF_ST");
3078 }
3079
3080 ATF_TC_BODY(bpfjit_st2, tc)
3081 {
3082 static struct bpf_insn insns[] = {
3083 BPF_STMT(BPF_ST, 0),
3084 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
3085 BPF_STMT(BPF_ST, BPF_MEMWORDS-1),
3086 BPF_STMT(BPF_LD+BPF_MEM, 0),
3087 BPF_STMT(BPF_RET+BPF_A, 0)
3088 };
3089
3090 uint8_t pkt[1]; /* the program doesn't read any data */
3091
3092 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3093
3094 RZ(rump_init());
3095
3096 ATF_CHECK(prog_validate(insns, insn_count));
3097 ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0);
3098 }
3099
3100 ATF_TC(bpfjit_st3);
3101 ATF_TC_HEAD(bpfjit_st3, tc)
3102 {
3103 atf_tc_set_md_var(tc, "descr",
3104 "Test JIT compilation of BPF_ST");
3105 }
3106
3107 ATF_TC_BODY(bpfjit_st3, tc)
3108 {
3109 static struct bpf_insn insns[] = {
3110 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
3111 BPF_STMT(BPF_ST, 0),
3112 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 100),
3113 BPF_STMT(BPF_ST, BPF_MEMWORDS-1),
3114 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 200),
3115 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 301, 2, 0),
3116 BPF_STMT(BPF_LD+BPF_MEM, BPF_MEMWORDS-1),
3117 BPF_STMT(BPF_RET+BPF_A, 0),
3118 BPF_STMT(BPF_LD+BPF_MEM, 0),
3119 BPF_STMT(BPF_RET+BPF_A, 0)
3120 };
3121
3122 bpfjit_func_t code;
3123 uint8_t pkt[2]; /* the program doesn't read any data */
3124
3125 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3126
3127 ATF_REQUIRE(BPF_MEMWORDS > 1);
3128
3129 RZ(rump_init());
3130
3131 ATF_CHECK(prog_validate(insns, insn_count));
3132
3133 rump_schedule();
3134 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3135 rump_unschedule();
3136 ATF_REQUIRE(code != NULL);
3137
3138 ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
3139 ATF_CHECK(jitcall(code, pkt, 2, 2) == 102);
3140
3141 rump_schedule();
3142 rumpns_bpfjit_free_code(code);
3143 rump_unschedule();
3144 }
3145
3146 ATF_TC(bpfjit_st4);
3147 ATF_TC_HEAD(bpfjit_st4, tc)
3148 {
3149 atf_tc_set_md_var(tc, "descr",
3150 "Test JIT compilation of BPF_ST");
3151 }
3152
3153 ATF_TC_BODY(bpfjit_st4, tc)
3154 {
3155 static struct bpf_insn insns[] = {
3156 BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
3157 BPF_STMT(BPF_ST, 5),
3158 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 100),
3159 BPF_STMT(BPF_ST, BPF_MEMWORDS-1),
3160 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 200),
3161 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 301, 2, 0),
3162 BPF_STMT(BPF_LD+BPF_MEM, BPF_MEMWORDS-1),
3163 BPF_STMT(BPF_RET+BPF_A, 0),
3164 BPF_STMT(BPF_LD+BPF_MEM, 5),
3165 BPF_STMT(BPF_RET+BPF_A, 0)
3166 };
3167
3168 bpfjit_func_t code;
3169 uint8_t pkt[2]; /* the program doesn't read any data */
3170
3171 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3172
3173 ATF_REQUIRE(BPF_MEMWORDS > 6);
3174
3175 RZ(rump_init());
3176
3177 ATF_CHECK(prog_validate(insns, insn_count));
3178
3179 rump_schedule();
3180 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3181 rump_unschedule();
3182 ATF_REQUIRE(code != NULL);
3183
3184 ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
3185 ATF_CHECK(jitcall(code, pkt, 2, 2) == 102);
3186
3187 rump_schedule();
3188 rumpns_bpfjit_free_code(code);
3189 rump_unschedule();
3190 }
3191
3192 ATF_TC(bpfjit_st5);
3193 ATF_TC_HEAD(bpfjit_st5, tc)
3194 {
3195 atf_tc_set_md_var(tc, "descr",
3196 "Test JIT compilation of BPF_ST");
3197 }
3198
3199 ATF_TC_BODY(bpfjit_st5, tc)
3200 {
3201 struct bpf_insn insns[5*BPF_MEMWORDS+2];
3202 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3203
3204 size_t k;
3205 bpfjit_func_t code;
3206 uint8_t pkt[BPF_MEMWORDS]; /* the program doesn't read any data */
3207
3208 memset(insns, 0, sizeof(insns));
3209
3210 /* for each k do M[k] = k */
3211 for (k = 0; k < BPF_MEMWORDS; k++) {
3212 insns[2*k].code = BPF_LD+BPF_IMM;
3213 insns[2*k].k = 3*k;
3214 insns[2*k+1].code = BPF_ST;
3215 insns[2*k+1].k = k;
3216 }
3217
3218 /* load wirelen into A */
3219 insns[2*BPF_MEMWORDS].code = BPF_LD+BPF_W+BPF_LEN;
3220
3221 /* for each k, if (A == k + 1) return M[k] */
3222 for (k = 0; k < BPF_MEMWORDS; k++) {
3223 insns[2*BPF_MEMWORDS+3*k+1].code = BPF_JMP+BPF_JEQ+BPF_K;
3224 insns[2*BPF_MEMWORDS+3*k+1].k = k+1;
3225 insns[2*BPF_MEMWORDS+3*k+1].jt = 0;
3226 insns[2*BPF_MEMWORDS+3*k+1].jf = 2;
3227 insns[2*BPF_MEMWORDS+3*k+2].code = BPF_LD+BPF_MEM;
3228 insns[2*BPF_MEMWORDS+3*k+2].k = k;
3229 insns[2*BPF_MEMWORDS+3*k+3].code = BPF_RET+BPF_A;
3230 insns[2*BPF_MEMWORDS+3*k+3].k = 0;
3231 }
3232
3233 insns[5*BPF_MEMWORDS+1].code = BPF_RET+BPF_K;
3234 insns[5*BPF_MEMWORDS+1].k = UINT32_MAX;
3235
3236 RZ(rump_init());
3237
3238 ATF_CHECK(prog_validate(insns, insn_count));
3239
3240 rump_schedule();
3241 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3242 rump_unschedule();
3243 ATF_REQUIRE(code != NULL);
3244
3245 for (k = 1; k <= sizeof(pkt); k++)
3246 ATF_CHECK(jitcall(code, pkt, k, k) == 3*(k-1));
3247
3248 rump_schedule();
3249 rumpns_bpfjit_free_code(code);
3250 rump_unschedule();
3251 }
3252
3253 ATF_TC(bpfjit_stx1);
3254 ATF_TC_HEAD(bpfjit_stx1, tc)
3255 {
3256 atf_tc_set_md_var(tc, "descr",
3257 "Test JIT compilation of BPF_STX");
3258 }
3259
3260 ATF_TC_BODY(bpfjit_stx1, tc)
3261 {
3262 static struct bpf_insn insns[] = {
3263 BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
3264 BPF_STMT(BPF_STX, 0),
3265 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0),
3266 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
3267 BPF_STMT(BPF_RET+BPF_A, 0)
3268 };
3269
3270 size_t i;
3271 bpfjit_func_t code;
3272 uint8_t pkt[16]; /* the program doesn't read any data */
3273
3274 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3275
3276 RZ(rump_init());
3277
3278 ATF_CHECK(prog_validate(insns, insn_count));
3279
3280 rump_schedule();
3281 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3282 rump_unschedule();
3283 ATF_REQUIRE(code != NULL);
3284
3285 for (i = 1; i <= sizeof(pkt); i++)
3286 ATF_CHECK(jitcall(code, pkt, i, sizeof(pkt)) == i);
3287
3288 rump_schedule();
3289 rumpns_bpfjit_free_code(code);
3290 rump_unschedule();
3291 }
3292
3293 ATF_TC(bpfjit_stx2);
3294 ATF_TC_HEAD(bpfjit_stx2, tc)
3295 {
3296 atf_tc_set_md_var(tc, "descr",
3297 "Test JIT compilation of BPF_STX");
3298 }
3299
3300 ATF_TC_BODY(bpfjit_stx2, tc)
3301 {
3302 static struct bpf_insn insns[] = {
3303 BPF_STMT(BPF_ST, 0),
3304 BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
3305 BPF_STMT(BPF_STX, BPF_MEMWORDS-1),
3306 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0),
3307 BPF_STMT(BPF_MISC+BPF_TXA, 0),
3308 BPF_STMT(BPF_RET+BPF_A, 0)
3309 };
3310
3311 uint8_t pkt[1]; /* the program doesn't read any data */
3312
3313 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3314
3315 RZ(rump_init());
3316
3317 ATF_CHECK(prog_validate(insns, insn_count));
3318 ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0);
3319 }
3320
3321 ATF_TC(bpfjit_stx3);
3322 ATF_TC_HEAD(bpfjit_stx3, tc)
3323 {
3324 atf_tc_set_md_var(tc, "descr",
3325 "Test JIT compilation of BPF_STX");
3326 }
3327
3328 ATF_TC_BODY(bpfjit_stx3, tc)
3329 {
3330 static struct bpf_insn insns[] = {
3331 BPF_STMT(BPF_STX, 6),
3332 BPF_STMT(BPF_ST, 1),
3333 BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
3334 BPF_STMT(BPF_STX, 5),
3335 BPF_STMT(BPF_STX, 2),
3336 BPF_STMT(BPF_STX, 3),
3337 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 1),
3338 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
3339 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 2),
3340 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
3341 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 3),
3342 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
3343 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 5),
3344 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
3345 BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 6),
3346 BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
3347 BPF_STMT(BPF_RET+BPF_A, 0)
3348 };
3349
3350 size_t i;
3351 bpfjit_func_t code;
3352 uint8_t pkt[16]; /* the program doesn't read any data */
3353
3354 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3355
3356 RZ(rump_init());
3357
3358 ATF_CHECK(prog_validate(insns, insn_count));
3359
3360 rump_schedule();
3361 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3362 rump_unschedule();
3363 ATF_REQUIRE(code != NULL);
3364
3365 for (i = 1; i <= sizeof(pkt); i++)
3366 ATF_CHECK(jitcall(code, pkt, i, sizeof(pkt)) == 3 * i);
3367
3368 rump_schedule();
3369 rumpns_bpfjit_free_code(code);
3370 rump_unschedule();
3371 }
3372
3373 ATF_TC(bpfjit_stx4);
3374 ATF_TC_HEAD(bpfjit_stx4, tc)
3375 {
3376 atf_tc_set_md_var(tc, "descr",
3377 "Test JIT compilation of BPF_STX");
3378 }
3379
3380 ATF_TC_BODY(bpfjit_stx4, tc)
3381 {
3382 struct bpf_insn insns[5*BPF_MEMWORDS+2];
3383 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3384
3385 size_t k;
3386 bpfjit_func_t code;
3387 uint8_t pkt[BPF_MEMWORDS]; /* the program doesn't read any data */
3388
3389 memset(insns, 0, sizeof(insns));
3390
3391 /* for each k do M[k] = k */
3392 for (k = 0; k < BPF_MEMWORDS; k++) {
3393 insns[2*k].code = BPF_LDX+BPF_W+BPF_IMM;
3394 insns[2*k].k = 3*k;
3395 insns[2*k+1].code = BPF_STX;
3396 insns[2*k+1].k = k;
3397 }
3398
3399 /* load wirelen into A */
3400 insns[2*BPF_MEMWORDS].code = BPF_LD+BPF_W+BPF_LEN;
3401
3402 /* for each k, if (A == k + 1) return M[k] */
3403 for (k = 0; k < BPF_MEMWORDS; k++) {
3404 insns[2*BPF_MEMWORDS+3*k+1].code = BPF_JMP+BPF_JEQ+BPF_K;
3405 insns[2*BPF_MEMWORDS+3*k+1].k = k+1;
3406 insns[2*BPF_MEMWORDS+3*k+1].jt = 0;
3407 insns[2*BPF_MEMWORDS+3*k+1].jf = 2;
3408 insns[2*BPF_MEMWORDS+3*k+2].code = BPF_LD+BPF_MEM;
3409 insns[2*BPF_MEMWORDS+3*k+2].k = k;
3410 insns[2*BPF_MEMWORDS+3*k+3].code = BPF_RET+BPF_A;
3411 insns[2*BPF_MEMWORDS+3*k+3].k = 0;
3412 }
3413
3414 insns[5*BPF_MEMWORDS+1].code = BPF_RET+BPF_K;
3415 insns[5*BPF_MEMWORDS+1].k = UINT32_MAX;
3416
3417 RZ(rump_init());
3418
3419 ATF_CHECK(prog_validate(insns, insn_count));
3420
3421 rump_schedule();
3422 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3423 rump_unschedule();
3424 ATF_REQUIRE(code != NULL);
3425
3426 for (k = 1; k <= sizeof(pkt); k++)
3427 ATF_CHECK(jitcall(code, pkt, k, k) == 3*(k-1));
3428
3429 rump_schedule();
3430 rumpns_bpfjit_free_code(code);
3431 rump_unschedule();
3432 }
3433
3434 ATF_TC(bpfjit_opt_ld_abs_1);
3435 ATF_TC_HEAD(bpfjit_opt_ld_abs_1, tc)
3436 {
3437 atf_tc_set_md_var(tc, "descr",
3438 "Test JIT compilation with length optimization "
3439 "applied to BPF_LD+BPF_ABS");
3440 }
3441
3442 ATF_TC_BODY(bpfjit_opt_ld_abs_1, tc)
3443 {
3444 static struct bpf_insn insns[] = {
3445 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
3446 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 8),
3447 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
3448 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
3449 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
3450 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4),
3451 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3),
3452 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
3453 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1),
3454 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3455 BPF_STMT(BPF_RET+BPF_K, 0),
3456 };
3457
3458 size_t i, j;
3459 bpfjit_func_t code;
3460 uint8_t pkt[2][34] = {
3461 {
3462 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3463 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3464 0x80, 0x03, 0x70, 0x0f,
3465 0x80, 0x03, 0x70, 0x23
3466 },
3467 {
3468 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3469 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3470 0x80, 0x03, 0x70, 0x23,
3471 0x80, 0x03, 0x70, 0x0f
3472 }
3473 };
3474
3475 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3476
3477 RZ(rump_init());
3478
3479 ATF_CHECK(prog_validate(insns, insn_count));
3480
3481 rump_schedule();
3482 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3483 rump_unschedule();
3484 ATF_REQUIRE(code != NULL);
3485
3486 for (i = 0; i < 2; i++) {
3487 for (j = 1; j < sizeof(pkt[i]); j++)
3488 ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
3489 ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
3490 }
3491
3492 rump_schedule();
3493 rumpns_bpfjit_free_code(code);
3494 rump_unschedule();
3495 }
3496
3497 ATF_TC(bpfjit_opt_ld_abs_2);
3498 ATF_TC_HEAD(bpfjit_opt_ld_abs_2, tc)
3499 {
3500 atf_tc_set_md_var(tc, "descr",
3501 "Test JIT compilation with length optimization "
3502 "applied to BPF_LD+BPF_ABS");
3503 }
3504
3505 ATF_TC_BODY(bpfjit_opt_ld_abs_2, tc)
3506 {
3507 static struct bpf_insn insns[] = {
3508 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
3509 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
3510 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
3511 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 6),
3512 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 5),
3513 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
3514 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 3),
3515 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
3516 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
3517 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3518 BPF_STMT(BPF_RET+BPF_K, 0),
3519 };
3520
3521 size_t i, j;
3522 bpfjit_func_t code;
3523 uint8_t pkt[2][34] = {
3524 {
3525 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3526 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3527 0x80, 0x03, 0x70, 0x0f,
3528 0x80, 0x03, 0x70, 0x23
3529 },
3530 {
3531 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3532 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3533 0x80, 0x03, 0x70, 0x23,
3534 0x80, 0x03, 0x70, 0x0f
3535 }
3536 };
3537
3538 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3539
3540 RZ(rump_init());
3541
3542 ATF_CHECK(prog_validate(insns, insn_count));
3543
3544 rump_schedule();
3545 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3546 rump_unschedule();
3547 ATF_REQUIRE(code != NULL);
3548
3549 for (i = 0; i < 2; i++) {
3550 for (j = 1; j < sizeof(pkt[i]); j++)
3551 ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
3552 ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
3553 }
3554
3555 rump_schedule();
3556 rumpns_bpfjit_free_code(code);
3557 rump_unschedule();
3558 }
3559
3560 ATF_TC(bpfjit_opt_ld_abs_3);
3561 ATF_TC_HEAD(bpfjit_opt_ld_abs_3, tc)
3562 {
3563 atf_tc_set_md_var(tc, "descr",
3564 "Test JIT compilation with length optimization "
3565 "applied to BPF_LD+BPF_ABS");
3566 }
3567
3568 ATF_TC_BODY(bpfjit_opt_ld_abs_3, tc)
3569 {
3570 static struct bpf_insn insns[] = {
3571 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
3572 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2),
3573 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
3574 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 6),
3575 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 5),
3576 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
3577 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3),
3578 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
3579 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
3580 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3581 BPF_STMT(BPF_RET+BPF_K, 0),
3582 };
3583
3584 size_t i, j;
3585 bpfjit_func_t code;
3586 uint8_t pkt[2][34] = {
3587 {
3588 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3589 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3590 0x80, 0x03, 0x70, 0x0f,
3591 0x80, 0x03, 0x70, 0x23
3592 },
3593 {
3594 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3595 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3596 0x80, 0x03, 0x70, 0x23,
3597 0x80, 0x03, 0x70, 0x0f
3598 }
3599 };
3600
3601 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3602
3603 RZ(rump_init());
3604
3605 ATF_CHECK(prog_validate(insns, insn_count));
3606
3607 rump_schedule();
3608 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3609 rump_unschedule();
3610 ATF_REQUIRE(code != NULL);
3611
3612 for (i = 0; i < 2; i++) {
3613 for (j = 1; j < sizeof(pkt[i]); j++)
3614 ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
3615 ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
3616 }
3617
3618 rump_schedule();
3619 rumpns_bpfjit_free_code(code);
3620 rump_unschedule();
3621 }
3622
3623 ATF_TC(bpfjit_opt_ld_ind_1);
3624 ATF_TC_HEAD(bpfjit_opt_ld_ind_1, tc)
3625 {
3626 atf_tc_set_md_var(tc, "descr",
3627 "Test JIT compilation with length optimization "
3628 "applied to BPF_LD+BPF_IND");
3629 }
3630
3631 ATF_TC_BODY(bpfjit_opt_ld_ind_1, tc)
3632 {
3633 static struct bpf_insn insns[] = {
3634 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 12),
3635 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 0),
3636 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 8),
3637 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 14),
3638 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
3639 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 18),
3640 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4),
3641 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3),
3642 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 18),
3643 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1),
3644 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3645 BPF_STMT(BPF_RET+BPF_K, 0),
3646 };
3647
3648 size_t i, j;
3649 bpfjit_func_t code;
3650 uint8_t pkt[2][34] = {
3651 {
3652 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3653 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3654 0x80, 0x03, 0x70, 0x0f,
3655 0x80, 0x03, 0x70, 0x23
3656 },
3657 {
3658 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3659 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3660 0x80, 0x03, 0x70, 0x23,
3661 0x80, 0x03, 0x70, 0x0f
3662 }
3663 };
3664
3665 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3666
3667 RZ(rump_init());
3668
3669 ATF_CHECK(prog_validate(insns, insn_count));
3670
3671 rump_schedule();
3672 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3673 rump_unschedule();
3674 ATF_REQUIRE(code != NULL);
3675
3676 for (i = 0; i < 2; i++) {
3677 for (j = 1; j < sizeof(pkt[i]); j++)
3678 ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
3679 ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
3680 }
3681
3682 rump_schedule();
3683 rumpns_bpfjit_free_code(code);
3684 rump_unschedule();
3685 }
3686
3687 ATF_TC(bpfjit_opt_ld_ind_2);
3688 ATF_TC_HEAD(bpfjit_opt_ld_ind_2, tc)
3689 {
3690 atf_tc_set_md_var(tc, "descr",
3691 "Test JIT compilation with length optimization "
3692 "applied to BPF_LD+BPF_IND");
3693 }
3694
3695 ATF_TC_BODY(bpfjit_opt_ld_ind_2, tc)
3696 {
3697 static struct bpf_insn insns[] = {
3698 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
3699 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 26),
3700 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
3701 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 30),
3702 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 6),
3703 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 5),
3704 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 30),
3705 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 3),
3706 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12),
3707 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
3708 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3709 BPF_STMT(BPF_RET+BPF_K, 0),
3710 };
3711
3712 size_t i, j;
3713 bpfjit_func_t code;
3714 uint8_t pkt[2][34] = {
3715 {
3716 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3717 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3718 0x80, 0x03, 0x70, 0x0f,
3719 0x80, 0x03, 0x70, 0x23
3720 },
3721 {
3722 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3723 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3724 0x80, 0x03, 0x70, 0x23,
3725 0x80, 0x03, 0x70, 0x0f
3726 }
3727 };
3728
3729 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3730
3731 RZ(rump_init());
3732
3733 ATF_CHECK(prog_validate(insns, insn_count));
3734
3735 rump_schedule();
3736 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3737 rump_unschedule();
3738 ATF_REQUIRE(code != NULL);
3739
3740 for (i = 0; i < 2; i++) {
3741 for (j = 1; j < sizeof(pkt[i]); j++)
3742 ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
3743 ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
3744 }
3745
3746 rump_schedule();
3747 rumpns_bpfjit_free_code(code);
3748 rump_unschedule();
3749 }
3750
3751 ATF_TC(bpfjit_opt_ld_ind_3);
3752 ATF_TC_HEAD(bpfjit_opt_ld_ind_3, tc)
3753 {
3754 atf_tc_set_md_var(tc, "descr",
3755 "Test JIT compilation with length optimization "
3756 "applied to BPF_LD+BPF_IND");
3757 }
3758
3759 ATF_TC_BODY(bpfjit_opt_ld_ind_3, tc)
3760 {
3761 static struct bpf_insn insns[] = {
3762 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 15),
3763 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15),
3764 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2),
3765 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 11),
3766 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 7),
3767 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 6),
3768 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 11),
3769 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 4),
3770 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
3771 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12),
3772 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
3773 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3774 BPF_STMT(BPF_RET+BPF_K, 0),
3775 };
3776
3777 size_t i, j;
3778 bpfjit_func_t code;
3779 uint8_t pkt[2][34] = {
3780 {
3781 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3782 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3783 0x80, 0x03, 0x70, 0x0f,
3784 0x80, 0x03, 0x70, 0x23
3785 },
3786 {
3787 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3788 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3789 0x80, 0x03, 0x70, 0x23,
3790 0x80, 0x03, 0x70, 0x0f
3791 }
3792 };
3793
3794 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3795
3796 RZ(rump_init());
3797
3798 ATF_CHECK(prog_validate(insns, insn_count));
3799
3800 rump_schedule();
3801 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3802 rump_unschedule();
3803 ATF_REQUIRE(code != NULL);
3804
3805 for (i = 0; i < 2; i++) {
3806 for (j = 1; j < sizeof(pkt[i]); j++)
3807 ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
3808 ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
3809 }
3810
3811 rump_schedule();
3812 rumpns_bpfjit_free_code(code);
3813 rump_unschedule();
3814 }
3815
3816 ATF_TC(bpfjit_opt_ld_ind_4);
3817 ATF_TC_HEAD(bpfjit_opt_ld_ind_4, tc)
3818 {
3819 atf_tc_set_md_var(tc, "descr",
3820 "Test JIT compilation with length optimization "
3821 "applied to BPF_LD+BPF_IND");
3822 }
3823
3824 ATF_TC_BODY(bpfjit_opt_ld_ind_4, tc)
3825 {
3826 static struct bpf_insn insns[] = {
3827 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 11),
3828 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 19),
3829 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2),
3830 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15),
3831 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 7),
3832 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 6),
3833 BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15),
3834 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 4),
3835 BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
3836 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12),
3837 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
3838 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3839 BPF_STMT(BPF_RET+BPF_K, 0),
3840 };
3841
3842 size_t i, j;
3843 bpfjit_func_t code;
3844 uint8_t pkt[2][34] = {
3845 {
3846 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3847 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3848 0x80, 0x03, 0x70, 0x0f,
3849 0x80, 0x03, 0x70, 0x23
3850 },
3851 {
3852 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
3853 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
3854 0x80, 0x03, 0x70, 0x23,
3855 0x80, 0x03, 0x70, 0x0f
3856 }
3857 };
3858
3859 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3860
3861 RZ(rump_init());
3862
3863 ATF_CHECK(prog_validate(insns, insn_count));
3864
3865 rump_schedule();
3866 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3867 rump_unschedule();
3868 ATF_REQUIRE(code != NULL);
3869
3870 for (i = 0; i < 2; i++) {
3871 for (j = 1; j < sizeof(pkt[i]); j++)
3872 ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
3873 ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
3874 }
3875
3876 rump_schedule();
3877 rumpns_bpfjit_free_code(code);
3878 rump_unschedule();
3879 }
3880
3881 ATF_TC(bpfjit_abc_ja);
3882 ATF_TC_HEAD(bpfjit_abc_ja, tc)
3883 {
3884 atf_tc_set_md_var(tc, "descr",
3885 "Test ABC optimization with a single BPF_JMP+BPF_JA");
3886 }
3887
3888 ATF_TC_BODY(bpfjit_abc_ja, tc)
3889 {
3890 static struct bpf_insn insns[] = {
3891 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3), /* min. length 4 */
3892 BPF_STMT(BPF_JMP+BPF_JA, 2),
3893 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, UINT32_MAX - 1),
3894 BPF_STMT(BPF_RET+BPF_K, 0),
3895 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 2), /* min. length 6 */
3896 BPF_STMT(BPF_RET+BPF_A, 0),
3897 BPF_STMT(BPF_RET+BPF_K, 1),
3898 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 6),
3899 BPF_STMT(BPF_RET+BPF_K, 2),
3900 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
3901 BPF_STMT(BPF_RET+BPF_K, 3),
3902 };
3903
3904 bpfjit_func_t code;
3905 uint8_t pkt[6] = {0, 0, /* UINT32_MAX: */ 255, 255, 255, 255};
3906
3907 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3908
3909 RZ(rump_init());
3910
3911 ATF_CHECK(prog_validate(insns, insn_count));
3912
3913 rump_schedule();
3914 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3915 rump_unschedule();
3916 ATF_REQUIRE(code != NULL);
3917
3918 ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
3919 ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
3920 ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
3921 ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
3922 ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
3923 ATF_CHECK(jitcall(code, pkt, 6, 6) == UINT32_MAX);
3924
3925 rump_schedule();
3926 rumpns_bpfjit_free_code(code);
3927 rump_unschedule();
3928 }
3929
3930 ATF_TC(bpfjit_abc_ja_over);
3931 ATF_TC_HEAD(bpfjit_abc_ja_over, tc)
3932 {
3933 atf_tc_set_md_var(tc, "descr",
3934 "Test ABC optimization when BPF_JMP+BPF_JA jumps over all loads");
3935 }
3936
3937 ATF_TC_BODY(bpfjit_abc_ja_over, tc)
3938 {
3939 static struct bpf_insn insns[] = {
3940 BPF_STMT(BPF_JMP+BPF_JA, 2),
3941 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3),
3942 BPF_STMT(BPF_RET+BPF_K, 0),
3943 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
3944 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 4),
3945 BPF_STMT(BPF_RET+BPF_K, 1),
3946 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 5),
3947 BPF_STMT(BPF_RET+BPF_K, 2),
3948 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 6),
3949 BPF_STMT(BPF_RET+BPF_K, 3),
3950 };
3951
3952 uint8_t pkt[1]; /* the program doesn't read any data */
3953
3954 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3955
3956 RZ(rump_init());
3957
3958 ATF_CHECK(prog_validate(insns, insn_count));
3959 ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX);
3960 }
3961
3962 ATF_TC(bpfjit_abc_ld_chain);
3963 ATF_TC_HEAD(bpfjit_abc_ld_chain, tc)
3964 {
3965 atf_tc_set_md_var(tc, "descr",
3966 "Test ABC optimization of a chain of BPF_LD instructions "
3967 "with exits leading to a single BPF_RET");
3968 }
3969
3970 ATF_TC_BODY(bpfjit_abc_ld_chain, tc)
3971 {
3972 static struct bpf_insn insns[] = {
3973 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3), /* min. length 4 */
3974 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 8, 0, 4),
3975 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 4), /* min. length 6 */
3976 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 7, 0, 2),
3977 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 6), /* min. length 10 */
3978 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 6, 0, 1),
3979 BPF_STMT(BPF_RET+BPF_K, 123456789),
3980 BPF_STMT(BPF_RET+BPF_K, 987654321),
3981 };
3982
3983 bpfjit_func_t code;
3984 uint8_t pkt[10] = {};
3985
3986 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
3987
3988 RZ(rump_init());
3989
3990 ATF_CHECK(prog_validate(insns, insn_count));
3991
3992 rump_schedule();
3993 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
3994 rump_unschedule();
3995 ATF_REQUIRE(code != NULL);
3996
3997 /* Packet is too short. */
3998 ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
3999 ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
4000 ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
4001
4002 /* !(pkt[3] == 8) => return 123456789 */
4003 ATF_CHECK(jitcall(code, pkt, 4, 4) == 123456789);
4004 ATF_CHECK(jitcall(code, pkt, 5, 5) == 123456789);
4005 ATF_CHECK(jitcall(code, pkt, 6, 6) == 123456789);
4006 ATF_CHECK(jitcall(code, pkt, 7, 7) == 123456789);
4007 ATF_CHECK(jitcall(code, pkt, 8, 8) == 123456789);
4008 ATF_CHECK(jitcall(code, pkt, 9, 9) == 123456789);
4009
4010 /* !(pkt[4:2] >= 7) => too short or return 123456789 */
4011 pkt[3] = 8;
4012 ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
4013 ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
4014 ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
4015 ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
4016 ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
4017 ATF_CHECK(jitcall(code, pkt, 6, 6) == 123456789);
4018 ATF_CHECK(jitcall(code, pkt, 9, 9) == 123456789);
4019
4020 /* !(pkt[6:4] > 6) => too short or return 987654321 */
4021 pkt[4] = pkt[5] = 1;
4022 ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
4023 ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
4024 ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
4025 ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
4026 ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
4027 ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
4028 ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
4029 ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
4030 ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
4031 ATF_CHECK(jitcall(code, pkt, 10, 10) == 987654321);
4032
4033 /* (pkt[6:4] > 6) => too short or return 123456789 */
4034 pkt[6] = pkt[7] = pkt[8] = pkt[9] = 1;
4035 ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
4036 ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
4037 ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
4038 ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
4039 ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
4040 ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
4041 ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
4042 ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
4043 ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
4044 ATF_CHECK(jitcall(code, pkt, 10, 10) == 123456789);
4045
4046 rump_schedule();
4047 rumpns_bpfjit_free_code(code);
4048 rump_unschedule();
4049 }
4050
4051 ATF_TC(bpfjit_examples_1);
4052 ATF_TC_HEAD(bpfjit_examples_1, tc)
4053 {
4054 atf_tc_set_md_var(tc, "descr",
4055 "Test the first example from bpf(4) - "
4056 "accept Reverse ARP requests");
4057 }
4058
4059 ATF_TC_BODY(bpfjit_examples_1, tc)
4060 {
4061 /*
4062 * The following filter is taken from the Reverse ARP
4063 * Daemon. It accepts only Reverse ARP requests.
4064 */
4065 struct bpf_insn insns[] = {
4066 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
4067 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8035, 0, 3),
4068 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20),
4069 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 3, 0, 1),
4070 BPF_STMT(BPF_RET+BPF_K, 42),
4071 BPF_STMT(BPF_RET+BPF_K, 0),
4072 };
4073
4074 bpfjit_func_t code;
4075 uint8_t pkt[22] = {};
4076
4077 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
4078
4079 RZ(rump_init());
4080
4081 ATF_CHECK(prog_validate(insns, insn_count));
4082
4083 rump_schedule();
4084 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
4085 rump_unschedule();
4086 ATF_REQUIRE(code != NULL);
4087
4088 /* Packet is too short. */
4089 ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
4090 ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
4091 ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
4092 ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
4093 ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
4094 ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
4095 ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
4096 ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
4097 ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
4098 ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
4099 ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
4100 ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
4101 ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
4102 ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
4103 ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
4104 ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
4105 ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
4106 ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
4107 ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
4108 ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
4109 ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
4110
4111 /* The packet doesn't match. */
4112 ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
4113
4114 /* Still no match after setting the protocol field. */
4115 pkt[12] = 0x80; pkt[13] = 0x35;
4116 ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
4117
4118 /* Set RARP message type. */
4119 pkt[21] = 3;
4120 ATF_CHECK(jitcall(code, pkt, 22, 22) == 42);
4121
4122 /* Packet is too short. */
4123 ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
4124 ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
4125 ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
4126 ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
4127 ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
4128 ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
4129 ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
4130 ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
4131 ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
4132 ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
4133 ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
4134 ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
4135 ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
4136 ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
4137 ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
4138 ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
4139 ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
4140 ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
4141 ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
4142 ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
4143 ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
4144
4145 /* Change RARP message type. */
4146 pkt[20] = 3;
4147 ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
4148
4149 rump_schedule();
4150 rumpns_bpfjit_free_code(code);
4151 rump_unschedule();
4152 }
4153
4154 ATF_TC(bpfjit_examples_2);
4155 ATF_TC_HEAD(bpfjit_examples_2, tc)
4156 {
4157 atf_tc_set_md_var(tc, "descr",
4158 "Test the second example from bpf(4) - "
4159 "accept IP packets between two specified hosts");
4160 }
4161
4162 ATF_TC_BODY(bpfjit_examples_2, tc)
4163 {
4164 /*
4165 * This filter accepts only IP packets between host 128.3.112.15
4166 * and 128.3.112.35.
4167 */
4168 static struct bpf_insn insns[] = {
4169 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
4170 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x0800, 0, 8),
4171 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
4172 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
4173 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
4174 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4),
4175 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3),
4176 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
4177 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1),
4178 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
4179 BPF_STMT(BPF_RET+BPF_K, 0),
4180 };
4181
4182 bpfjit_func_t code;
4183 uint8_t pkt[34] = {};
4184
4185 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
4186
4187 RZ(rump_init());
4188
4189 ATF_CHECK(prog_validate(insns, insn_count));
4190
4191 rump_schedule();
4192 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
4193 rump_unschedule();
4194 ATF_REQUIRE(code != NULL);
4195
4196 /* Packet is too short. */
4197 ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
4198 ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
4199 ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
4200 ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
4201 ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
4202 ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
4203 ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
4204 ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
4205 ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
4206 ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
4207 ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
4208 ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
4209 ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
4210 ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
4211 ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
4212 ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
4213 ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
4214 ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
4215 ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
4216 ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
4217 ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
4218 ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
4219 ATF_CHECK(jitcall(code, pkt, 23, 23) == 0);
4220 ATF_CHECK(jitcall(code, pkt, 24, 24) == 0);
4221 ATF_CHECK(jitcall(code, pkt, 25, 25) == 0);
4222 ATF_CHECK(jitcall(code, pkt, 26, 26) == 0);
4223 ATF_CHECK(jitcall(code, pkt, 27, 27) == 0);
4224 ATF_CHECK(jitcall(code, pkt, 28, 28) == 0);
4225 ATF_CHECK(jitcall(code, pkt, 29, 29) == 0);
4226 ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
4227 ATF_CHECK(jitcall(code, pkt, 31, 31) == 0);
4228 ATF_CHECK(jitcall(code, pkt, 32, 32) == 0);
4229 ATF_CHECK(jitcall(code, pkt, 33, 33) == 0);
4230
4231 /* The packet doesn't match. */
4232 ATF_CHECK(jitcall(code, pkt, 34, 34) == 0);
4233
4234 /* Still no match after setting the protocol field. */
4235 pkt[12] = 8;
4236 ATF_CHECK(jitcall(code, pkt, 34, 34) == 0);
4237
4238 pkt[26] = 128; pkt[27] = 3; pkt[28] = 112; pkt[29] = 15;
4239 ATF_CHECK(jitcall(code, pkt, 34, 34) == 0);
4240
4241 pkt[30] = 128; pkt[31] = 3; pkt[32] = 112; pkt[33] = 35;
4242 ATF_CHECK(jitcall(code, pkt, 34, 34) == UINT32_MAX);
4243
4244 /* Swap the ip addresses. */
4245 pkt[26] = 128; pkt[27] = 3; pkt[28] = 112; pkt[29] = 35;
4246 ATF_CHECK(jitcall(code, pkt, 34, 34) == 0);
4247
4248 pkt[30] = 128; pkt[31] = 3; pkt[32] = 112; pkt[33] = 15;
4249 ATF_CHECK(jitcall(code, pkt, 34, 34) == UINT32_MAX);
4250
4251 /* Packet is too short. */
4252 ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
4253 ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
4254 ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
4255 ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
4256 ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
4257 ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
4258 ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
4259 ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
4260 ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
4261 ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
4262 ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
4263 ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
4264 ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
4265 ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
4266 ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
4267 ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
4268 ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
4269 ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
4270 ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
4271 ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
4272 ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
4273 ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
4274 ATF_CHECK(jitcall(code, pkt, 23, 23) == 0);
4275 ATF_CHECK(jitcall(code, pkt, 24, 24) == 0);
4276 ATF_CHECK(jitcall(code, pkt, 25, 25) == 0);
4277 ATF_CHECK(jitcall(code, pkt, 26, 26) == 0);
4278 ATF_CHECK(jitcall(code, pkt, 27, 27) == 0);
4279 ATF_CHECK(jitcall(code, pkt, 28, 28) == 0);
4280 ATF_CHECK(jitcall(code, pkt, 29, 29) == 0);
4281 ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
4282 ATF_CHECK(jitcall(code, pkt, 31, 31) == 0);
4283 ATF_CHECK(jitcall(code, pkt, 32, 32) == 0);
4284 ATF_CHECK(jitcall(code, pkt, 33, 33) == 0);
4285
4286 /* Change the protocol field. */
4287 pkt[13] = 8;
4288 ATF_CHECK(jitcall(code, pkt, 34, 34) == 0);
4289
4290 rump_schedule();
4291 rumpns_bpfjit_free_code(code);
4292 rump_unschedule();
4293 }
4294
4295 ATF_TC(bpfjit_examples_3);
4296 ATF_TC_HEAD(bpfjit_examples_3, tc)
4297 {
4298 atf_tc_set_md_var(tc, "descr",
4299 "Test the third example from bpf(4) - "
4300 "accept TCP finger packets");
4301 }
4302
4303 ATF_TC_BODY(bpfjit_examples_3, tc)
4304 {
4305 /*
4306 * This filter returns only TCP finger packets.
4307 */
4308 struct bpf_insn insns[] = {
4309 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
4310 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x0800, 0, 10),
4311 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 23),
4312 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 6, 0, 8),
4313 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20),
4314 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 0x1fff, 6, 0),
4315 BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 14),
4316 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 14),
4317 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 2, 0),
4318 BPF_STMT(BPF_LD+BPF_H+BPF_IND, 16),
4319 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 0, 1),
4320 BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
4321 BPF_STMT(BPF_RET+BPF_K, 0),
4322 };
4323
4324 bpfjit_func_t code;
4325 uint8_t pkt[30] = {};
4326
4327 /* Set IP fragment offset to non-zero. */
4328 pkt[20] = 1; pkt[21] = 1;
4329
4330 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
4331
4332 RZ(rump_init());
4333
4334 ATF_CHECK(prog_validate(insns, insn_count));
4335
4336 rump_schedule();
4337 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
4338 rump_unschedule();
4339 ATF_REQUIRE(code != NULL);
4340
4341 /* Packet is too short. */
4342 ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
4343 ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
4344 ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
4345 ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
4346 ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
4347 ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
4348 ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
4349 ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
4350 ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
4351 ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
4352 ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
4353 ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
4354 ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
4355 ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
4356 ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
4357 ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
4358 ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
4359 ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
4360 ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
4361 ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
4362 ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
4363 ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
4364 ATF_CHECK(jitcall(code, pkt, 23, 23) == 0);
4365 ATF_CHECK(jitcall(code, pkt, 24, 24) == 0);
4366 ATF_CHECK(jitcall(code, pkt, 25, 25) == 0);
4367 ATF_CHECK(jitcall(code, pkt, 26, 26) == 0);
4368 ATF_CHECK(jitcall(code, pkt, 27, 27) == 0);
4369 ATF_CHECK(jitcall(code, pkt, 28, 28) == 0);
4370 ATF_CHECK(jitcall(code, pkt, 29, 29) == 0);
4371
4372 /* The packet doesn't match. */
4373 ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
4374
4375 /* Still no match after setting the protocol field. */
4376 pkt[12] = 8;
4377 ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
4378
4379 /* Get one step closer to the match. */
4380 pkt[23] = 6;
4381 ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
4382
4383 /* Set IP fragment offset to zero. */
4384 pkt[20] = 0x20; pkt[21] = 0;
4385 ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
4386
4387 /* Set IP header length to 12. */
4388 pkt[14] = 0xd3;
4389 ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
4390
4391 /* Match one branch of the program. */
4392 pkt[27] = 79;
4393 ATF_CHECK(jitcall(code, pkt, 30, 30) == UINT32_MAX);
4394
4395 /* Match the other branch of the program. */
4396 pkt[29] = 79; pkt[27] = 0;
4397 ATF_CHECK(jitcall(code, pkt, 30, 30) == UINT32_MAX);
4398
4399 /* Packet is too short. */
4400 ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
4401 ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
4402 ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
4403 ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
4404 ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
4405 ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
4406 ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
4407 ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
4408 ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
4409 ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
4410 ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
4411 ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
4412 ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
4413 ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
4414 ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
4415 ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
4416 ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
4417 ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
4418 ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
4419 ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
4420 ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
4421 ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
4422 ATF_CHECK(jitcall(code, pkt, 23, 23) == 0);
4423 ATF_CHECK(jitcall(code, pkt, 24, 24) == 0);
4424 ATF_CHECK(jitcall(code, pkt, 25, 25) == 0);
4425 ATF_CHECK(jitcall(code, pkt, 26, 26) == 0);
4426 ATF_CHECK(jitcall(code, pkt, 27, 27) == 0);
4427 ATF_CHECK(jitcall(code, pkt, 28, 28) == 0);
4428 ATF_CHECK(jitcall(code, pkt, 29, 29) == 0);
4429
4430 /* Set IP header length to 16. Packet is too short. */
4431 pkt[14] = 4;
4432 ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
4433
4434 rump_schedule();
4435 rumpns_bpfjit_free_code(code);
4436 rump_unschedule();
4437 }
4438
4439 ATF_TC(bpfjit_cop_no_ctx);
4440 ATF_TC_HEAD(bpfjit_cop_no_ctx, tc)
4441 {
4442 atf_tc_set_md_var(tc, "descr", "Test that BPF_MISC|BPF_COP "
4443 "instruction can't be accepted without a context");
4444 }
4445
4446 ATF_TC_BODY(bpfjit_cop_no_ctx, tc)
4447 {
4448 static struct bpf_insn insns[] = {
4449 BPF_STMT(BPF_MISC+BPF_COP, 0),
4450 BPF_STMT(BPF_RET+BPF_K, 7)
4451 };
4452
4453 bpfjit_func_t code;
4454 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
4455
4456 RZ(rump_init());
4457
4458 ATF_CHECK(!prog_validate(insns, insn_count));
4459
4460 rump_schedule();
4461 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
4462 rump_unschedule();
4463 ATF_CHECK(code == NULL);
4464 }
4465
4466 ATF_TC(bpfjit_copx_no_ctx);
4467 ATF_TC_HEAD(bpfjit_copx_no_ctx, tc)
4468 {
4469 atf_tc_set_md_var(tc, "descr", "Test that BPF_MISC|BPF_COPX "
4470 "instruction can't be accepted without a context");
4471 }
4472
4473 ATF_TC_BODY(bpfjit_copx_no_ctx, tc)
4474 {
4475 static struct bpf_insn insns[] = {
4476 BPF_STMT(BPF_MISC+BPF_COPX, 0),
4477 BPF_STMT(BPF_RET+BPF_K, 7)
4478 };
4479
4480 bpfjit_func_t code;
4481 size_t insn_count = sizeof(insns) / sizeof(insns[0]);
4482
4483 RZ(rump_init());
4484
4485 ATF_CHECK(!prog_validate(insns, insn_count));
4486
4487 rump_schedule();
4488 code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
4489 rump_unschedule();
4490 ATF_CHECK(code == NULL);
4491 }
4492
4493 ATF_TP_ADD_TCS(tp)
4494 {
4495
4496 /*
4497 * For every new test please also add a similar test
4498 * to ../../lib/libbpfjit/t_bpfjit.c
4499 */
4500 ATF_TP_ADD_TC(tp, bpfjit_empty);
4501 ATF_TP_ADD_TC(tp, bpfjit_ret_k);
4502 ATF_TP_ADD_TC(tp, bpfjit_bad_ret_k);
4503 ATF_TP_ADD_TC(tp, bpfjit_alu_add_k);
4504 ATF_TP_ADD_TC(tp, bpfjit_alu_sub_k);
4505 ATF_TP_ADD_TC(tp, bpfjit_alu_mul_k);
4506 ATF_TP_ADD_TC(tp, bpfjit_alu_div0_k);
4507 ATF_TP_ADD_TC(tp, bpfjit_alu_div1_k);
4508 ATF_TP_ADD_TC(tp, bpfjit_alu_div2_k);
4509 ATF_TP_ADD_TC(tp, bpfjit_alu_div4_k);
4510 ATF_TP_ADD_TC(tp, bpfjit_alu_div10_k);
4511 ATF_TP_ADD_TC(tp, bpfjit_alu_div10000_k);
4512 ATF_TP_ADD_TC(tp, bpfjit_alu_div7609801_k);
4513 ATF_TP_ADD_TC(tp, bpfjit_alu_div80000000_k);
4514 ATF_TP_ADD_TC(tp, bpfjit_alu_mod0_k);
4515 ATF_TP_ADD_TC(tp, bpfjit_alu_mod1_k);
4516 ATF_TP_ADD_TC(tp, bpfjit_alu_mod2_k);
4517 ATF_TP_ADD_TC(tp, bpfjit_alu_mod4_k);
4518 ATF_TP_ADD_TC(tp, bpfjit_alu_mod10_k);
4519 ATF_TP_ADD_TC(tp, bpfjit_alu_mod10000_k);
4520 ATF_TP_ADD_TC(tp, bpfjit_alu_mod7609801_k);
4521 ATF_TP_ADD_TC(tp, bpfjit_alu_mod80000000_k);
4522 ATF_TP_ADD_TC(tp, bpfjit_alu_and_k);
4523 ATF_TP_ADD_TC(tp, bpfjit_alu_or_k);
4524 ATF_TP_ADD_TC(tp, bpfjit_alu_xor_k);
4525 ATF_TP_ADD_TC(tp, bpfjit_alu_lsh_k);
4526 ATF_TP_ADD_TC(tp, bpfjit_alu_lsh0_k);
4527 ATF_TP_ADD_TC(tp, bpfjit_alu_rsh_k);
4528 ATF_TP_ADD_TC(tp, bpfjit_alu_rsh0_k);
4529 ATF_TP_ADD_TC(tp, bpfjit_alu_modulo_k);
4530 ATF_TP_ADD_TC(tp, bpfjit_alu_add_x);
4531 ATF_TP_ADD_TC(tp, bpfjit_alu_sub_x);
4532 ATF_TP_ADD_TC(tp, bpfjit_alu_mul_x);
4533 ATF_TP_ADD_TC(tp, bpfjit_alu_div0_x);
4534 ATF_TP_ADD_TC(tp, bpfjit_alu_div1_x);
4535 ATF_TP_ADD_TC(tp, bpfjit_alu_div2_x);
4536 ATF_TP_ADD_TC(tp, bpfjit_alu_div4_x);
4537 ATF_TP_ADD_TC(tp, bpfjit_alu_div10_x);
4538 ATF_TP_ADD_TC(tp, bpfjit_alu_div10000_x);
4539 ATF_TP_ADD_TC(tp, bpfjit_alu_div7609801_x);
4540 ATF_TP_ADD_TC(tp, bpfjit_alu_div80000000_x);
4541 ATF_TP_ADD_TC(tp, bpfjit_alu_mod0_x);
4542 ATF_TP_ADD_TC(tp, bpfjit_alu_mod1_x);
4543 ATF_TP_ADD_TC(tp, bpfjit_alu_mod2_x);
4544 ATF_TP_ADD_TC(tp, bpfjit_alu_mod4_x);
4545 ATF_TP_ADD_TC(tp, bpfjit_alu_mod10_x);
4546 ATF_TP_ADD_TC(tp, bpfjit_alu_mod10000_x);
4547 ATF_TP_ADD_TC(tp, bpfjit_alu_mod7609801_x);
4548 ATF_TP_ADD_TC(tp, bpfjit_alu_mod80000000_x);
4549 ATF_TP_ADD_TC(tp, bpfjit_alu_and_x);
4550 ATF_TP_ADD_TC(tp, bpfjit_alu_or_x);
4551 ATF_TP_ADD_TC(tp, bpfjit_alu_xor_x);
4552 ATF_TP_ADD_TC(tp, bpfjit_alu_lsh_x);
4553 ATF_TP_ADD_TC(tp, bpfjit_alu_lsh0_x);
4554 ATF_TP_ADD_TC(tp, bpfjit_alu_rsh_x);
4555 ATF_TP_ADD_TC(tp, bpfjit_alu_rsh0_x);
4556 ATF_TP_ADD_TC(tp, bpfjit_alu_modulo_x);
4557 ATF_TP_ADD_TC(tp, bpfjit_alu_neg);
4558 ATF_TP_ADD_TC(tp, bpfjit_jmp_ja);
4559 ATF_TP_ADD_TC(tp, bpfjit_jmp_ja_invalid);
4560 ATF_TP_ADD_TC(tp, bpfjit_jmp_ja_overflow);
4561 ATF_TP_ADD_TC(tp, bpfjit_jmp_jgt_k);
4562 ATF_TP_ADD_TC(tp, bpfjit_jmp_jge_k);
4563 ATF_TP_ADD_TC(tp, bpfjit_jmp_jeq_k);
4564 ATF_TP_ADD_TC(tp, bpfjit_jmp_jset_k);
4565 ATF_TP_ADD_TC(tp, bpfjit_jmp_modulo_k);
4566 ATF_TP_ADD_TC(tp, bpfjit_jmp_jgt_x);
4567 ATF_TP_ADD_TC(tp, bpfjit_jmp_jge_x);
4568 ATF_TP_ADD_TC(tp, bpfjit_jmp_jeq_x);
4569 ATF_TP_ADD_TC(tp, bpfjit_jmp_jset_x);
4570 ATF_TP_ADD_TC(tp, bpfjit_jmp_jeq_x_noinit_ax);
4571 ATF_TP_ADD_TC(tp, bpfjit_jmp_modulo_x);
4572 ATF_TP_ADD_TC(tp, bpfjit_ld_abs);
4573 ATF_TP_ADD_TC(tp, bpfjit_ld_abs_k_overflow);
4574 ATF_TP_ADD_TC(tp, bpfjit_ld_ind);
4575 ATF_TP_ADD_TC(tp, bpfjit_ld_ind_k_overflow);
4576 ATF_TP_ADD_TC(tp, bpfjit_ld_ind_x_overflow1);
4577 ATF_TP_ADD_TC(tp, bpfjit_ld_ind_x_overflow2);
4578 ATF_TP_ADD_TC(tp, bpfjit_ld_len);
4579 ATF_TP_ADD_TC(tp, bpfjit_ld_imm);
4580 ATF_TP_ADD_TC(tp, bpfjit_ldx_imm1);
4581 ATF_TP_ADD_TC(tp, bpfjit_ldx_imm2);
4582 ATF_TP_ADD_TC(tp, bpfjit_ldx_len1);
4583 ATF_TP_ADD_TC(tp, bpfjit_ldx_len2);
4584 ATF_TP_ADD_TC(tp, bpfjit_ldx_msh);
4585 ATF_TP_ADD_TC(tp, bpfjit_misc_tax);
4586 ATF_TP_ADD_TC(tp, bpfjit_misc_txa);
4587 ATF_TP_ADD_TC(tp, bpfjit_st1);
4588 ATF_TP_ADD_TC(tp, bpfjit_st2);
4589 ATF_TP_ADD_TC(tp, bpfjit_st3);
4590 ATF_TP_ADD_TC(tp, bpfjit_st4);
4591 ATF_TP_ADD_TC(tp, bpfjit_st5);
4592 ATF_TP_ADD_TC(tp, bpfjit_stx1);
4593 ATF_TP_ADD_TC(tp, bpfjit_stx2);
4594 ATF_TP_ADD_TC(tp, bpfjit_stx3);
4595 ATF_TP_ADD_TC(tp, bpfjit_stx4);
4596 ATF_TP_ADD_TC(tp, bpfjit_opt_ld_abs_1);
4597 ATF_TP_ADD_TC(tp, bpfjit_opt_ld_abs_2);
4598 ATF_TP_ADD_TC(tp, bpfjit_opt_ld_abs_3);
4599 ATF_TP_ADD_TC(tp, bpfjit_opt_ld_ind_1);
4600 ATF_TP_ADD_TC(tp, bpfjit_opt_ld_ind_2);
4601 ATF_TP_ADD_TC(tp, bpfjit_opt_ld_ind_3);
4602 ATF_TP_ADD_TC(tp, bpfjit_opt_ld_ind_4);
4603 ATF_TP_ADD_TC(tp, bpfjit_abc_ja);
4604 ATF_TP_ADD_TC(tp, bpfjit_abc_ja_over);
4605 ATF_TP_ADD_TC(tp, bpfjit_abc_ld_chain);
4606 ATF_TP_ADD_TC(tp, bpfjit_examples_1);
4607 ATF_TP_ADD_TC(tp, bpfjit_examples_2);
4608 ATF_TP_ADD_TC(tp, bpfjit_examples_3);
4609 ATF_TP_ADD_TC(tp, bpfjit_cop_no_ctx);
4610 ATF_TP_ADD_TC(tp, bpfjit_copx_no_ctx);
4611
4612 return atf_no_error();
4613 }
4614