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