1 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
2
3 #![allow(clippy::unreadable_literal)]
4 #![cfg(feature = "cranelift")]
5
6 extern crate rbpf;
7 mod common;
8
9 use rbpf::{assembler::assemble, helpers};
10
11 use crate::common::{TCP_SACK_ASM, TCP_SACK_MATCH, TCP_SACK_NOMATCH};
12
13 macro_rules! test_cranelift {
14 ($name:ident, $prog:expr, $expected:expr) => {
15 #[test]
16 fn $name() {
17 let prog = assemble($prog).unwrap();
18 let mut vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
19 vm.cranelift_compile().unwrap();
20 assert_eq!(vm.execute_program_cranelift().unwrap(), $expected);
21 }
22 };
23 ($name:ident, $prog:expr, $mem:expr, $expected:expr) => {
24 #[test]
25 fn $name() {
26 let prog = assemble($prog).unwrap();
27 let mem = &mut $mem;
28 let mut vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
29 vm.cranelift_compile().unwrap();
30 assert_eq!(vm.execute_program_cranelift(mem).unwrap(), $expected);
31 }
32 };
33 }
34
35 test_cranelift!(
36 test_cranelift_add,
37 "
38 mov32 r0, 0
39 mov32 r1, 2
40 add32 r0, 1
41 add32 r0, r1
42 exit
43 ",
44 0x3
45 );
46
47 test_cranelift!(
48 test_cranelift_alu64_arith,
49 "
50 mov r0, 0
51 mov r1, 1
52 mov r2, 2
53 mov r3, 3
54 mov r4, 4
55 mov r5, 5
56 mov r6, 6
57 mov r7, 7
58 mov r8, 8
59 mov r9, 9
60 add r0, 23
61 add r0, r7
62 sub r0, 13
63 sub r0, r1
64 mul r0, 7
65 mul r0, r3
66 div r0, 2
67 div r0, r4
68 exit
69 ",
70 0x2a
71 );
72
73 test_cranelift!(
74 test_cranelift_alu64_bit,
75 "
76 mov r0, 0
77 mov r1, 1
78 mov r2, 2
79 mov r3, 3
80 mov r4, 4
81 mov r5, 5
82 mov r6, 6
83 mov r7, 7
84 mov r8, 8
85 or r0, r5
86 or r0, 0xa0
87 and r0, 0xa3
88 mov r9, 0x91
89 and r0, r9
90 lsh r0, 32
91 lsh r0, 22
92 lsh r0, r8
93 rsh r0, 32
94 rsh r0, 19
95 rsh r0, r7
96 xor r0, 0x03
97 xor r0, r2
98 exit
99 ",
100 0x11
101 );
102
103 test_cranelift!(
104 test_cranelift_alu_arith,
105 "
106 mov32 r0, 0
107 mov32 r1, 1
108 mov32 r2, 2
109 mov32 r3, 3
110 mov32 r4, 4
111 mov32 r5, 5
112 mov32 r6, 6
113 mov32 r7, 7
114 mov32 r8, 8
115 mov32 r9, 9
116 add32 r0, 23
117 add32 r0, r7
118 sub32 r0, 13
119 sub32 r0, r1
120 mul32 r0, 7
121 mul32 r0, r3
122 div32 r0, 2
123 div32 r0, r4
124 exit
125 ",
126 0x2a
127 );
128
129 test_cranelift!(
130 test_cranelift_alu_bit,
131 "
132 mov32 r0, 0
133 mov32 r1, 1
134 mov32 r2, 2
135 mov32 r3, 3
136 mov32 r4, 4
137 mov32 r5, 5
138 mov32 r6, 6
139 mov32 r7, 7
140 mov32 r8, 8
141 or32 r0, r5
142 or32 r0, 0xa0
143 and32 r0, 0xa3
144 mov32 r9, 0x91
145 and32 r0, r9
146 lsh32 r0, 22
147 lsh32 r0, r8
148 rsh32 r0, 19
149 rsh32 r0, r7
150 xor32 r0, 0x03
151 xor32 r0, r2
152 exit
153 ",
154 0x11
155 );
156
157 test_cranelift!(
158 test_cranelift_arsh32_high_shift,
159 "
160 mov r0, 8
161 lddw r1, 0x100000001
162 arsh32 r0, r1
163 exit
164 ",
165 0x4
166 );
167
168 test_cranelift!(
169 test_cranelift_arsh,
170 "
171 mov32 r0, 0xf8
172 lsh32 r0, 28
173 arsh32 r0, 16
174 exit
175 ",
176 0xffff8000
177 );
178
179 test_cranelift!(
180 test_cranelift_arsh64,
181 "
182 mov32 r0, 1
183 lsh r0, 63
184 arsh r0, 55
185 mov32 r1, 5
186 arsh r0, r1
187 exit
188 ",
189 0xfffffffffffffff8
190 );
191
192 test_cranelift!(
193 test_cranelift_arsh_reg,
194 "
195 mov32 r0, 0xf8
196 mov32 r1, 16
197 lsh32 r0, 28
198 arsh32 r0, r1
199 exit
200 ",
201 0xffff8000
202 );
203
204 test_cranelift!(
205 test_cranelift_be16,
206 "
207 ldxh r0, [r1]
208 be16 r0
209 exit
210 ",
211 [0x11, 0x22],
212 0x1122
213 );
214
215 test_cranelift!(
216 test_cranelift_be16_high,
217 "
218 ldxdw r0, [r1]
219 be16 r0
220 exit
221 ",
222 [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88],
223 0x1122
224 );
225
226 test_cranelift!(
227 test_cranelift_be32,
228 "
229 ldxw r0, [r1]
230 be32 r0
231 exit
232 ",
233 [0x11, 0x22, 0x33, 0x44],
234 0x11223344
235 );
236
237 test_cranelift!(
238 test_cranelift_be32_high,
239 "
240 ldxdw r0, [r1]
241 be32 r0
242 exit
243 ",
244 [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88],
245 0x11223344
246 );
247
248 test_cranelift!(
249 test_cranelift_be64,
250 "
251 ldxdw r0, [r1]
252 be64 r0
253 exit
254 ",
255 [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88],
256 0x1122334455667788
257 );
258
259 #[test]
test_cranelift_call()260 fn test_cranelift_call() {
261 let prog = assemble(
262 "
263 mov r1, 1
264 mov r2, 2
265 mov r3, 3
266 mov r4, 4
267 mov r5, 5
268 call 0
269 exit",
270 )
271 .unwrap();
272
273 let mut vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
274 vm.register_helper(0, helpers::gather_bytes).unwrap();
275 vm.cranelift_compile().unwrap();
276 assert_eq!(vm.execute_program_cranelift().unwrap(), 0x0102030405);
277 }
278
279 #[test]
280 #[should_panic(expected = "[CRANELIFT] Error: unknown helper function (id: 0x3f)")]
test_cranelift_err_call_unreg()281 fn test_cranelift_err_call_unreg() {
282 let prog = assemble(
283 "
284 mov r1, 1
285 mov r2, 2
286 mov r3, 3
287 mov r4, 4
288 mov r5, 5
289 call 63
290 exit
291 ",
292 )
293 .unwrap();
294 let mut vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
295 vm.cranelift_compile().unwrap();
296 }
297
298 #[test]
test_cranelift_call_memfrob()299 fn test_cranelift_call_memfrob() {
300 let prog = assemble(
301 "
302 mov r6, r1
303 add r1, 2
304 mov r2, 4
305 call 1
306 ldxdw r0, [r6]
307 be64 r0
308 exit",
309 )
310 .unwrap();
311
312 let mut vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
313 vm.register_helper(1, helpers::memfrob).unwrap();
314 let mem = &mut [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];
315 vm.cranelift_compile().unwrap();
316 assert_eq!(
317 vm.execute_program_cranelift(mem).unwrap(),
318 0x102292e2f2c0708
319 );
320 }
321
322 test_cranelift!(
323 test_cranelift_div32_high_divisor,
324 "
325 mov r0, 12
326 lddw r1, 0x100000004
327 div32 r0, r1
328 exit
329 ",
330 0x3
331 );
332
333 test_cranelift!(
334 test_cranelift_div32_imm,
335 "
336 lddw r0, 0x10000000c
337 div32 r0, 4
338 exit
339 ",
340 0x3
341 );
342
343 test_cranelift!(
344 test_cranelift_div32_reg,
345 "
346 lddw r0, 0x10000000c
347 mov r1, 4
348 div32 r0, r1
349 exit
350 ",
351 0x3
352 );
353
354 test_cranelift!(
355 test_cranelift_div64_imm,
356 "
357 mov r0, 0xc
358 lsh r0, 32
359 div r0, 4
360 exit
361 ",
362 0x300000000
363 );
364
365 test_cranelift!(
366 test_cranelift_div64_reg,
367 "
368 mov r0, 0xc
369 lsh r0, 32
370 mov r1, 4
371 div r0, r1
372 exit
373 ",
374 0x300000000
375 );
376
377 test_cranelift!(
378 test_cranelift_early_exit,
379 "
380 mov r0, 3
381 exit
382 mov r0, 4
383 exit
384 ",
385 0x3
386 );
387
388 test_cranelift!(
389 test_cranelift_div64_by_zero_imm,
390 "
391 mov32 r0, 1
392 div r0, 0
393 exit
394 ",
395 0x0
396 );
397
398 test_cranelift!(
399 test_cranelift_div_by_zero_imm,
400 "
401 mov32 r0, 1
402 div32 r0, 0
403 exit
404 ",
405 0x0
406 );
407
408 test_cranelift!(
409 test_cranelift_mod64_by_zero_imm,
410 "
411 mov32 r0, 1
412 mod r0, 0
413 exit
414 ",
415 0x1
416 );
417
418 test_cranelift!(
419 test_cranelift_mod_by_zero_imm,
420 "
421 mov32 r0, 1
422 mod32 r0, 0
423 exit
424 ",
425 0x1
426 );
427
428 test_cranelift!(
429 test_cranelift_div64_by_zero_reg,
430 "
431 mov32 r0, 1
432 mov32 r1, 0
433 div r0, r1
434 exit
435 ",
436 0x0
437 );
438
439 test_cranelift!(
440 test_cranelift_div_by_zero_reg,
441 "
442 mov32 r0, 1
443 mov32 r1, 0
444 div32 r0, r1
445 exit
446 ",
447 0x0
448 );
449
450 test_cranelift!(
451 test_cranelift_mod64_by_zero_reg,
452 "
453 mov32 r0, 1
454 mov32 r1, 0
455 mod r0, r1
456 exit
457 ",
458 0x1
459 );
460
461 test_cranelift!(
462 test_cranelift_mod_by_zero_reg,
463 "
464 mov32 r0, 1
465 mov32 r1, 0
466 mod32 r0, r1
467 exit
468 ",
469 0x1
470 );
471
472 #[test]
473 // #[should_panic(expected = "Error: out of bounds memory store (insn #1)")]
474 #[ignore = "We have stack OOB checks, but we don't yet catch the trap code and convert it into a panic"]
test_cranelift_err_stack_out_of_bound()475 fn test_cranelift_err_stack_out_of_bound() {
476 let prog = [
477 0x72, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
478 0x00,
479 ];
480 let mut vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
481 vm.cranelift_compile().unwrap();
482 vm.execute_program_cranelift().unwrap();
483 }
484
485 test_cranelift!(
486 test_cranelift_exit,
487 "
488 mov r0, 0
489 exit
490 ",
491 0x0
492 );
493
494 test_cranelift!(
495 test_cranelift_ja,
496 "
497 mov r0, 1
498 ja +1
499 mov r0, 2
500 exit
501 ",
502 0x1
503 );
504
505 test_cranelift!(
506 test_cranelift_jeq_imm,
507 "
508 mov32 r0, 0
509 mov32 r1, 0xa
510 jeq r1, 0xb, +4
511 mov32 r0, 1
512 mov32 r1, 0xb
513 jeq r1, 0xb, +1
514 mov32 r0, 2
515 exit
516 ",
517 0x1
518 );
519
520 test_cranelift!(
521 test_cranelift_jeq_reg,
522 "
523 mov32 r0, 0
524 mov32 r1, 0xa
525 mov32 r2, 0xb
526 jeq r1, r2, +4
527 mov32 r0, 1
528 mov32 r1, 0xb
529 jeq r1, r2, +1
530 mov32 r0, 2
531 exit
532 ",
533 0x1
534 );
535
536 test_cranelift!(
537 test_cranelift_jge_imm,
538 "
539 mov32 r0, 0
540 mov32 r1, 0xa
541 jge r1, 0xb, +4
542 mov32 r0, 1
543 mov32 r1, 0xc
544 jge r1, 0xb, +1
545 mov32 r0, 2
546 exit
547 ",
548 0x1
549 );
550
551 test_cranelift!(
552 test_cranelift_jle_imm,
553 "
554 mov32 r0, 0
555 mov32 r1, 5
556 jle r1, 4, +1
557 jle r1, 6, +1
558 exit
559 jle r1, 5, +1
560 exit
561 mov32 r0, 1
562 exit
563 ",
564 0x1
565 );
566
567 test_cranelift!(
568 test_cranelift_jle_reg,
569 "
570 mov r0, 0
571 mov r1, 5
572 mov r2, 4
573 mov r3, 6
574 jle r1, r2, +2
575 jle r1, r1, +1
576 exit
577 jle r1, r3, +1
578 exit
579 mov r0, 1
580 exit
581 ",
582 0x1
583 );
584
585 test_cranelift!(
586 test_cranelift_jgt_imm,
587 "
588 mov32 r0, 0
589 mov32 r1, 5
590 jgt r1, 6, +2
591 jgt r1, 5, +1
592 jgt r1, 4, +1
593 exit
594 mov32 r0, 1
595 exit
596 ",
597 0x1
598 );
599
600 test_cranelift!(
601 test_cranelift_jgt_reg,
602 "
603 mov r0, 0
604 mov r1, 5
605 mov r2, 6
606 mov r3, 4
607 jgt r1, r2, +2
608 jgt r1, r1, +1
609 jgt r1, r3, +1
610 exit
611 mov r0, 1
612 exit
613 ",
614 0x1
615 );
616
617 test_cranelift!(
618 test_cranelift_jlt_imm,
619 "
620 mov32 r0, 0
621 mov32 r1, 5
622 jlt r1, 4, +2
623 jlt r1, 5, +1
624 jlt r1, 6, +1
625 exit
626 mov32 r0, 1
627 exit
628 ",
629 0x1
630 );
631
632 test_cranelift!(
633 test_cranelift_jlt_reg,
634 "
635 mov r0, 0
636 mov r1, 5
637 mov r2, 4
638 mov r3, 6
639 jlt r1, r2, +2
640 jlt r1, r1, +1
641 jlt r1, r3, +1
642 exit
643 mov r0, 1
644 exit
645 ",
646 0x1
647 );
648
649 test_cranelift!(
650 test_cranelift_jit_bounce,
651 "
652 mov r0, 1
653 mov r6, r0
654 mov r7, r6
655 mov r8, r7
656 mov r9, r8
657 mov r0, r9
658 exit
659 ",
660 0x1
661 );
662
663 test_cranelift!(
664 test_cranelift_jne_reg,
665 "
666 mov32 r0, 0
667 mov32 r1, 0xb
668 mov32 r2, 0xb
669 jne r1, r2, +4
670 mov32 r0, 1
671 mov32 r1, 0xa
672 jne r1, r2, +1
673 mov32 r0, 2
674 exit
675 ",
676 0x1
677 );
678
679 test_cranelift!(
680 test_cranelift_jset_imm,
681 "
682 mov32 r0, 0
683 mov32 r1, 0x7
684 jset r1, 0x8, +4
685 mov32 r0, 1
686 mov32 r1, 0x9
687 jset r1, 0x8, +1
688 mov32 r0, 2
689 exit
690 ",
691 0x1
692 );
693
694 test_cranelift!(
695 test_cranelift_jset_reg,
696 "
697 mov32 r0, 0
698 mov32 r1, 0x7
699 mov32 r2, 0x8
700 jset r1, r2, +4
701 mov32 r0, 1
702 mov32 r1, 0x9
703 jset r1, r2, +1
704 mov32 r0, 2
705 exit
706 ",
707 0x1
708 );
709
710 test_cranelift!(
711 test_cranelift_jsge_imm,
712 "
713 mov32 r0, 0
714 mov r1, -2
715 jsge r1, -1, +5
716 jsge r1, 0, +4
717 mov32 r0, 1
718 mov r1, -1
719 jsge r1, -1, +1
720 mov32 r0, 2
721 exit
722 ",
723 0x1
724 );
725
726 test_cranelift!(
727 test_cranelift_jsge_reg,
728 "
729 mov32 r0, 0
730 mov r1, -2
731 mov r2, -1
732 mov32 r3, 0
733 jsge r1, r2, +5
734 jsge r1, r3, +4
735 mov32 r0, 1
736 mov r1, r2
737 jsge r1, r2, +1
738 mov32 r0, 2
739 exit
740 ",
741 0x1
742 );
743
744 test_cranelift!(
745 test_cranelift_jsle_imm,
746 "
747 mov32 r0, 0
748 mov r1, -2
749 jsle r1, -3, +1
750 jsle r1, -1, +1
751 exit
752 mov32 r0, 1
753 jsle r1, -2, +1
754 mov32 r0, 2
755 exit
756 ",
757 0x1
758 );
759
760 test_cranelift!(
761 test_cranelift_jsle_reg,
762 "
763 mov32 r0, 0
764 mov r1, -1
765 mov r2, -2
766 mov32 r3, 0
767 jsle r1, r2, +1
768 jsle r1, r3, +1
769 exit
770 mov32 r0, 1
771 mov r1, r2
772 jsle r1, r2, +1
773 mov32 r0, 2
774 exit
775 ",
776 0x1
777 );
778
779 test_cranelift!(
780 test_cranelift_jsgt_imm,
781 "
782 mov32 r0, 0
783 mov r1, -2
784 jsgt r1, -1, +4
785 mov32 r0, 1
786 mov32 r1, 0
787 jsgt r1, -1, +1
788 mov32 r0, 2
789 exit
790 ",
791 0x1
792 );
793
794 test_cranelift!(
795 test_cranelift_jsgt_reg,
796 "
797 mov32 r0, 0
798 mov r1, -2
799 mov r2, -1
800 jsgt r1, r2, +4
801 mov32 r0, 1
802 mov32 r1, 0
803 jsgt r1, r2, +1
804 mov32 r0, 2
805 exit
806 ",
807 0x1
808 );
809
810 test_cranelift!(
811 test_cranelift_jslt_imm,
812 "
813 mov32 r0, 0
814 mov r1, -2
815 jslt r1, -3, +2
816 jslt r1, -2, +1
817 jslt r1, -1, +1
818 exit
819 mov32 r0, 1
820 exit
821 ",
822 0x1
823 );
824
825 test_cranelift!(
826 test_cranelift_jslt_reg,
827 "
828 mov32 r0, 0
829 mov r1, -2
830 mov r2, -3
831 mov r3, -1
832 jslt r1, r1, +2
833 jslt r1, r2, +1
834 jslt r1, r3, +1
835 exit
836 mov32 r0, 1
837 exit
838 ",
839 0x1
840 );
841
842 test_cranelift!(
843 test_cranelift_jeq32_imm,
844 "
845 mov r9, 1
846 lsh r9, 32
847 mov32 r0, 0x0
848 mov32 r1, 0xa
849 jeq32 r1, 0xb, +5
850 mov32 r0, 1
851 mov r1, 0xb
852 or r1, r9
853 jeq32 r1, 0xb, +1
854 mov32 r0, 2
855 exit
856 ",
857 0x1
858 );
859
860 test_cranelift!(
861 test_cranelift_jeq32_reg,
862 "
863 mov r9, 1
864 lsh r9, 32
865 mov32 r0, 0
866 mov32 r1, 0xa
867 mov32 r2, 0xb
868 jeq32 r1, r2, +5
869 mov32 r0, 1
870 mov32 r1, 0xb
871 or r1, r9
872 jeq32 r1, r2, +1
873 mov32 r0, 2
874 exit
875 ",
876 0x1
877 );
878
879 test_cranelift!(
880 test_cranelift_jge32_imm,
881 "
882 mov r9, 1
883 lsh r9, 32
884 mov32 r0, 0
885 mov32 r1, 0xa
886 jge32 r1, 0xb, +5
887 mov32 r0, 1
888 or r1, r9
889 mov32 r1, 0xc
890 jge32 r1, 0xb, +1
891 mov32 r0, 2
892 exit
893 ",
894 0x1
895 );
896
897 test_cranelift!(
898 test_cranelift_jge32_reg,
899 "
900 mov r9, 1
901 lsh r9, 32
902 mov32 r0, 0
903 mov32 r1, 0xa
904 mov32 r2, 0xb
905 jge32 r1, r2, +5
906 mov32 r0, 1
907 or r1, r9
908 mov32 r1, 0xc
909 jge32 r1, r2, +1
910 mov32 r0, 2
911 exit
912 ",
913 0x1
914 );
915
916 test_cranelift!(
917 test_cranelift_jgt32_imm,
918 "
919 mov r9, 1
920 lsh r9, 32
921 mov32 r0, 0
922 mov32 r1, 5
923 or r1, r9
924 jgt32 r1, 6, +4
925 jgt32 r1, 5, +3
926 jgt32 r1, 4, +1
927 exit
928 mov32 r0, 1
929 exit
930 ",
931 0x1
932 );
933
934 test_cranelift!(
935 test_cranelift_jgt32_reg,
936 "
937 mov r9, 1
938 lsh r9, 32
939 mov r0, 0
940 mov r1, 5
941 mov32 r1, 5
942 or r1, r9
943 mov r2, 6
944 mov r3, 4
945 jgt32 r1, r2, +4
946 jgt32 r1, r1, +3
947 jgt32 r1, r3, +1
948 exit
949 mov r0, 1
950 exit
951 ",
952 0x1
953 );
954
955 test_cranelift!(
956 test_cranelift_jle32_imm,
957 "
958 mov r9, 1
959 lsh r9, 32
960 mov32 r0, 0
961 mov32 r1, 5
962 or r1, r9
963 jle32 r1, 4, +5
964 jle32 r1, 6, +1
965 exit
966 jle32 r1, 5, +1
967 exit
968 mov32 r0, 1
969 exit
970 ",
971 0x1
972 );
973
974 test_cranelift!(
975 test_cranelift_jle32_reg,
976 "
977 mov r9, 1
978 lsh r9, 32
979 mov r0, 0
980 mov r1, 5
981 mov r2, 4
982 mov r3, 6
983 or r1, r9
984 jle32 r1, r2, +5
985 jle32 r1, r1, +1
986 exit
987 jle32 r1, r3, +1
988 exit
989 mov r0, 1
990 exit
991 ",
992 0x1
993 );
994
995 test_cranelift!(
996 test_cranelift_jlt32_imm,
997 "
998 mov r9, 1
999 lsh r9, 32
1000 mov32 r0, 0
1001 mov32 r1, 5
1002 or r1, r9
1003 jlt32 r1, 4, +4
1004 jlt32 r1, 5, +3
1005 jlt32 r1, 6, +1
1006 exit
1007 mov32 r0, 1
1008 exit
1009 ",
1010 0x1
1011 );
1012
1013 test_cranelift!(
1014 test_cranelift_jlt32_reg,
1015 "
1016 mov r9, 1
1017 lsh r9, 32
1018 mov r0, 0
1019 mov r1, 5
1020 mov r2, 4
1021 mov r3, 6
1022 or r1, r9
1023 jlt32 r1, r2, +4
1024 jlt32 r1, r1, +3
1025 jlt32 r1, r3, +1
1026 exit
1027 mov r0, 1
1028 exit
1029 ",
1030 0x1
1031 );
1032
1033 test_cranelift!(
1034 test_cranelift_jne32_imm,
1035 "
1036 mov r9, 1
1037 lsh r9, 32
1038 mov32 r0, 0
1039 mov32 r1, 0xb
1040 or r1, r9
1041 jne32 r1, 0xb, +4
1042 mov32 r0, 1
1043 mov32 r1, 0xa
1044 or r1, r9
1045 jne32 r1, 0xb, +1
1046 mov32 r0, 2
1047 exit
1048 ",
1049 0x1
1050 );
1051
1052 test_cranelift!(
1053 test_cranelift_jne32_reg,
1054 "
1055 mov r9, 1
1056 lsh r9, 32
1057 mov32 r0, 0
1058 mov32 r1, 0xb
1059 or r1, r9
1060 mov32 r2, 0xb
1061 jne32 r1, r2, +4
1062 mov32 r0, 1
1063 mov32 r1, 0xa
1064 or r1, r9
1065 jne32 r1, r2, +1
1066 mov32 r0, 2
1067 exit
1068 ",
1069 0x1
1070 );
1071
1072 test_cranelift!(
1073 test_cranelift_jset32_imm,
1074 "
1075 mov r9, 1
1076 lsh r9, 32
1077 mov32 r0, 0
1078 mov32 r1, 0x7
1079 or r1, r9
1080 jset32 r1, 0x8, +4
1081 mov32 r0, 1
1082 mov32 r1, 0x9
1083 jset32 r1, 0x8, +1
1084 mov32 r0, 2
1085 exit
1086 ",
1087 0x1
1088 );
1089
1090 test_cranelift!(
1091 test_cranelift_jset32_reg,
1092 "
1093 mov r9, 1
1094 lsh r9, 32
1095 mov32 r0, 0
1096 mov32 r1, 0x7
1097 or r1, r9
1098 mov32 r2, 0x8
1099 jset32 r1, r2, +4
1100 mov32 r0, 1
1101 mov32 r1, 0x9
1102 jset32 r1, r2, +1
1103 mov32 r0, 2
1104 exit
1105 ",
1106 0x1
1107 );
1108
1109 test_cranelift!(
1110 test_cranelift_jsge32_imm,
1111 "
1112 mov r9, 1
1113 lsh r9, 32
1114 mov32 r0, 0
1115 mov32 r1, -2
1116 or r1, r9
1117 jsge32 r1, -1, +5
1118 jsge32 r1, 0, +4
1119 mov32 r0, 1
1120 mov r1, -1
1121 jsge32 r1, -1, +1
1122 mov32 r0, 2
1123 exit
1124 ",
1125 0x1
1126 );
1127
1128 test_cranelift!(
1129 test_cranelift_jsge32_reg,
1130 "
1131 mov r9, 1
1132 lsh r9, 32
1133 mov32 r0, 0
1134 mov32 r1, -2
1135 or r1, r9
1136 mov r2, -1
1137 mov32 r3, 0
1138 jsge32 r1, r2, +5
1139 jsge32 r1, r3, +4
1140 mov32 r0, 1
1141 mov r1, r2
1142 jsge32 r1, r2, +1
1143 mov32 r0, 2
1144 exit
1145 ",
1146 0x1
1147 );
1148
1149 test_cranelift!(
1150 test_cranelift_jsgt32_imm,
1151 "
1152 mov r9, 1
1153 lsh r9, 32
1154 mov32 r0, 0
1155 mov32 r1, -2
1156 or r1, r9
1157 jsgt32 r1, -1, +4
1158 mov32 r0, 1
1159 mov32 r1, 0
1160 jsgt32 r1, -1, +1
1161 mov32 r0, 2
1162 exit
1163 ",
1164 0x1
1165 );
1166
1167 test_cranelift!(
1168 test_cranelift_jsgt32_reg,
1169 "
1170 mov r9, 1
1171 lsh r9, 32
1172 mov32 r0, 0
1173 mov32 r1, -2
1174 or r1, r9
1175 mov r2, -1
1176 jsgt32 r1, r2, +4
1177 mov32 r0, 1
1178 mov32 r1, 0
1179 jsgt32 r1, r2, +1
1180 mov32 r0, 2
1181 exit
1182 ",
1183 0x1
1184 );
1185
1186 test_cranelift!(
1187 test_cranelift_jsle32_imm,
1188 "
1189 mov r9, 1
1190 lsh r9, 32
1191 mov32 r0, 0
1192 mov32 r1, -2
1193 or r1, r9
1194 jsle32 r1, -3, +5
1195 jsle32 r1, -1, +1
1196 exit
1197 mov32 r0, 1
1198 jsle32 r1, -2, +1
1199 mov32 r0, 2
1200 exit
1201 ",
1202 0x1
1203 );
1204
1205 test_cranelift!(
1206 test_cranelift_jsle32_reg,
1207 "
1208 mov r9, 1
1209 lsh r9, 32
1210 mov32 r0, 0
1211 mov32 r1, -2
1212 or r1, r9
1213 mov r2, -3
1214 mov32 r3, 0
1215 jsle32 r1, r2, +6
1216 jsle32 r1, r3, +1
1217 exit
1218 mov32 r0, 1
1219 mov r1, r2
1220 jsle32 r1, r2, +1
1221 mov32 r0, 2
1222 exit
1223 ",
1224 0x1
1225 );
1226
1227 test_cranelift!(
1228 test_cranelift_jslt32_imm,
1229 "
1230 mov r9, 1
1231 lsh r9, 32
1232 mov32 r0, 0
1233 mov32 r1, -2
1234 or r1, r9
1235 jslt32 r1, -3, +4
1236 jslt32 r1, -2, +3
1237 jslt32 r1, -1, +1
1238 exit
1239 mov32 r0, 1
1240 exit
1241 ",
1242 0x1
1243 );
1244
1245 test_cranelift!(
1246 test_cranelift_jslt32_reg,
1247 "
1248 mov r9, 1
1249 lsh r9, 32
1250 mov32 r0, 0
1251 mov32 r1, -2
1252 or r1, r9
1253 mov r2, -3
1254 mov r3, -1
1255 jslt32 r1, r1, +4
1256 jslt32 r1, r2, +3
1257 jslt32 r1, r3, +1
1258 exit
1259 mov32 r0, 1
1260 exit
1261 ",
1262 0x1
1263 );
1264
1265 test_cranelift!(
1266 test_cranelift_lddw,
1267 "
1268 lddw r0, 0x1122334455667788
1269 exit
1270 ",
1271 0x1122334455667788
1272 );
1273
1274 test_cranelift!(
1275 test_cranelift_lddw2,
1276 "
1277 lddw r0, 0x0000000080000000
1278 exit
1279 ",
1280 0x80000000
1281 );
1282
1283 test_cranelift!(
1284 test_cranelift_ldxb_all,
1285 "
1286 mov r0, r1
1287 ldxb r9, [r0+0]
1288 lsh r9, 0
1289 ldxb r8, [r0+1]
1290 lsh r8, 4
1291 ldxb r7, [r0+2]
1292 lsh r7, 8
1293 ldxb r6, [r0+3]
1294 lsh r6, 12
1295 ldxb r5, [r0+4]
1296 lsh r5, 16
1297 ldxb r4, [r0+5]
1298 lsh r4, 20
1299 ldxb r3, [r0+6]
1300 lsh r3, 24
1301 ldxb r2, [r0+7]
1302 lsh r2, 28
1303 ldxb r1, [r0+8]
1304 lsh r1, 32
1305 ldxb r0, [r0+9]
1306 lsh r0, 36
1307 or r0, r1
1308 or r0, r2
1309 or r0, r3
1310 or r0, r4
1311 or r0, r5
1312 or r0, r6
1313 or r0, r7
1314 or r0, r8
1315 or r0, r9
1316 exit
1317 ",
1318 [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09],
1319 0x9876543210
1320 );
1321
1322 test_cranelift!(
1323 test_cranelift_ldxb,
1324 "
1325 ldxb r0, [r1+2]
1326 exit
1327 ",
1328 [0xaa, 0xbb, 0x11, 0xcc, 0xdd],
1329 0x11
1330 );
1331
1332 test_cranelift!(
1333 test_cranelift_ldxdw,
1334 "
1335 ldxdw r0, [r1+2]
1336 exit
1337 ",
1338 [0xaa, 0xbb, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0xcc, 0xdd],
1339 0x8877665544332211
1340 );
1341
1342 test_cranelift!(
1343 test_cranelift_ldxh_all,
1344 "
1345 mov r0, r1
1346 ldxh r9, [r0+0]
1347 be16 r9
1348 lsh r9, 0
1349 ldxh r8, [r0+2]
1350 be16 r8
1351 lsh r8, 4
1352 ldxh r7, [r0+4]
1353 be16 r7
1354 lsh r7, 8
1355 ldxh r6, [r0+6]
1356 be16 r6
1357 lsh r6, 12
1358 ldxh r5, [r0+8]
1359 be16 r5
1360 lsh r5, 16
1361 ldxh r4, [r0+10]
1362 be16 r4
1363 lsh r4, 20
1364 ldxh r3, [r0+12]
1365 be16 r3
1366 lsh r3, 24
1367 ldxh r2, [r0+14]
1368 be16 r2
1369 lsh r2, 28
1370 ldxh r1, [r0+16]
1371 be16 r1
1372 lsh r1, 32
1373 ldxh r0, [r0+18]
1374 be16 r0
1375 lsh r0, 36
1376 or r0, r1
1377 or r0, r2
1378 or r0, r3
1379 or r0, r4
1380 or r0, r5
1381 or r0, r6
1382 or r0, r7
1383 or r0, r8
1384 or r0, r9
1385 exit
1386 ",
1387 [
1388 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00,
1389 0x07, 0x00, 0x08, 0x00, 0x09
1390 ],
1391 0x9876543210
1392 );
1393
1394 test_cranelift!(
1395 test_cranelift_ldxh_all2,
1396 "
1397 mov r0, r1
1398 ldxh r9, [r0+0]
1399 be16 r9
1400 ldxh r8, [r0+2]
1401 be16 r8
1402 ldxh r7, [r0+4]
1403 be16 r7
1404 ldxh r6, [r0+6]
1405 be16 r6
1406 ldxh r5, [r0+8]
1407 be16 r5
1408 ldxh r4, [r0+10]
1409 be16 r4
1410 ldxh r3, [r0+12]
1411 be16 r3
1412 ldxh r2, [r0+14]
1413 be16 r2
1414 ldxh r1, [r0+16]
1415 be16 r1
1416 ldxh r0, [r0+18]
1417 be16 r0
1418 or r0, r1
1419 or r0, r2
1420 or r0, r3
1421 or r0, r4
1422 or r0, r5
1423 or r0, r6
1424 or r0, r7
1425 or r0, r8
1426 or r0, r9
1427 exit
1428 ",
1429 [
1430 0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00,
1431 0x80, 0x01, 0x00, 0x02, 0x00
1432 ],
1433 0x3ff
1434 );
1435
1436 test_cranelift!(
1437 test_cranelift_ldxh,
1438 "
1439 ldxh r0, [r1+2]
1440 exit
1441 ",
1442 [0xaa, 0xbb, 0x11, 0x22, 0xcc, 0xdd],
1443 0x2211
1444 );
1445
1446 test_cranelift!(
1447 test_cranelift_ldxh_same_reg,
1448 "
1449 mov r0, r1
1450 sth [r0], 0x1234
1451 ldxh r0, [r0]
1452 exit
1453 ",
1454 [0xff, 0xff],
1455 0x1234
1456 );
1457
1458 test_cranelift!(
1459 test_cranelift_ldxw_all,
1460 "
1461 mov r0, r1
1462 ldxw r9, [r0+0]
1463 be32 r9
1464 ldxw r8, [r0+4]
1465 be32 r8
1466 ldxw r7, [r0+8]
1467 be32 r7
1468 ldxw r6, [r0+12]
1469 be32 r6
1470 ldxw r5, [r0+16]
1471 be32 r5
1472 ldxw r4, [r0+20]
1473 be32 r4
1474 ldxw r3, [r0+24]
1475 be32 r3
1476 ldxw r2, [r0+28]
1477 be32 r2
1478 ldxw r1, [r0+32]
1479 be32 r1
1480 ldxw r0, [r0+36]
1481 be32 r0
1482 or r0, r1
1483 or r0, r2
1484 or r0, r3
1485 or r0, r4
1486 or r0, r5
1487 or r0, r6
1488 or r0, r7
1489 or r0, r8
1490 or r0, r9
1491 exit
1492 ",
1493 [
1494 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1495 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1496 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00
1497 ],
1498 0x030f0f
1499 );
1500
1501 test_cranelift!(
1502 test_cranelift_ldxw,
1503 "
1504 ldxw r0, [r1+2]
1505 exit
1506 ",
1507 [0xaa, 0xbb, 0x11, 0x22, 0x33, 0x44, 0xcc, 0xdd],
1508 0x44332211
1509 );
1510
1511 test_cranelift!(
1512 test_cranelift_le16,
1513 "
1514 ldxh r0, [r1]
1515 le16 r0
1516 exit
1517 ",
1518 [0x22, 0x11],
1519 0x1122
1520 );
1521
1522 test_cranelift!(
1523 test_cranelift_le32,
1524 "
1525 ldxw r0, [r1]
1526 le32 r0
1527 exit
1528 ",
1529 [0x44, 0x33, 0x22, 0x11],
1530 0x11223344
1531 );
1532
1533 test_cranelift!(
1534 test_cranelift_le64,
1535 "
1536 ldxdw r0, [r1]
1537 le64 r0
1538 exit
1539 ",
1540 [0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11],
1541 0x1122334455667788
1542 );
1543
1544 test_cranelift!(
1545 test_cranelift_lsh_reg,
1546 "
1547 mov r0, 0x1
1548 mov r7, 4
1549 lsh r0, r7
1550 exit
1551 ",
1552 0x10
1553 );
1554
1555 test_cranelift!(
1556 test_cranelift_mod,
1557 "
1558 mov32 r0, 5748
1559 mod32 r0, 92
1560 mov32 r1, 13
1561 mod32 r0, r1
1562 exit
1563 ",
1564 0x5
1565 );
1566
1567 test_cranelift!(
1568 test_cranelift_mod32,
1569 "
1570 lddw r0, 0x100000003
1571 mod32 r0, 3
1572 exit
1573 ",
1574 0x0
1575 );
1576
1577 test_cranelift!(
1578 test_cranelift_mod64,
1579 "
1580 mov32 r0, -1316649930
1581 lsh r0, 32
1582 or r0, 0x100dc5c8
1583 mov32 r1, 0xdde263e
1584 lsh r1, 32
1585 or r1, 0x3cbef7f3
1586 mod r0, r1
1587 mod r0, 0x658f1778
1588 exit
1589 ",
1590 0x30ba5a04
1591 );
1592
1593 test_cranelift!(
1594 test_cranelift_mov,
1595 "
1596 mov32 r1, 1
1597 mov32 r0, r1
1598 exit
1599 ",
1600 0x1
1601 );
1602
1603 test_cranelift!(
1604 test_cranelift_mul32_imm,
1605 "
1606 mov r0, 3
1607 mul32 r0, 4
1608 exit
1609 ",
1610 0xc
1611 );
1612
1613 test_cranelift!(
1614 test_cranelift_mul32_reg,
1615 "
1616 mov r0, 3
1617 mov r1, 4
1618 mul32 r0, r1
1619 exit
1620 ",
1621 0xc
1622 );
1623
1624 test_cranelift!(
1625 test_cranelift_mul32_reg_overflow,
1626 "
1627 mov r0, 0x40000001
1628 mov r1, 4
1629 mul32 r0, r1
1630 exit
1631 ",
1632 0x4
1633 );
1634
1635 test_cranelift!(
1636 test_cranelift_mul64_imm,
1637 "
1638 mov r0, 0x40000001
1639 mul r0, 4
1640 exit
1641 ",
1642 0x100000004
1643 );
1644
1645 test_cranelift!(
1646 test_cranelift_mul64_reg,
1647 "
1648 mov r0, 0x40000001
1649 mov r1, 4
1650 mul r0, r1
1651 exit
1652 ",
1653 0x100000004
1654 );
1655
1656 test_cranelift!(
1657 test_cranelift_mul_loop,
1658 "
1659 mov r0, 0x7
1660 add r1, 0xa
1661 lsh r1, 0x20
1662 rsh r1, 0x20
1663 jeq r1, 0x0, +4
1664 mov r0, 0x7
1665 mul r0, 0x7
1666 add r1, -1
1667 jne r1, 0x0, -3
1668 exit
1669 ",
1670 0x75db9c97
1671 );
1672
1673 test_cranelift!(
1674 test_cranelift_neg64,
1675 "
1676 mov32 r0, 2
1677 neg r0
1678 exit
1679 ",
1680 0xfffffffffffffffe
1681 );
1682
1683 test_cranelift!(
1684 test_cranelift_neg,
1685 "
1686 mov32 r0, 2
1687 neg32 r0
1688 exit
1689 ",
1690 0xfffffffe
1691 );
1692
1693 test_cranelift!(
1694 test_cranelift_prime,
1695 "
1696 mov r1, 67
1697 mov r0, 0x1
1698 mov r2, 0x2
1699 jgt r1, 0x2, +4
1700 ja +10
1701 add r2, 0x1
1702 mov r0, 0x1
1703 jge r2, r1, +7
1704 mov r3, r1
1705 div r3, r2
1706 mul r3, r2
1707 mov r4, r1
1708 sub r4, r3
1709 mov r0, 0x0
1710 jne r4, 0x0, -10
1711 exit
1712 ",
1713 1
1714 );
1715
1716 test_cranelift!(
1717 test_cranelift_rhs32,
1718 "
1719 xor r0, r0
1720 sub r0, 1
1721 rsh32 r0, 8
1722 exit
1723 ",
1724 0x00ffffff
1725 );
1726
1727 test_cranelift!(
1728 test_cranelift_rsh_reg,
1729 "
1730 mov r0, 0x10
1731 mov r7, 4
1732 rsh r0, r7
1733 exit
1734 ",
1735 0x1
1736 );
1737
1738 test_cranelift!(
1739 test_cranelift_stack,
1740 "
1741 mov r1, 51
1742 stdw [r10-16], 0xab
1743 stdw [r10-8], 0xcd
1744 and r1, 1
1745 lsh r1, 3
1746 mov r2, r10
1747 add r2, r1
1748 ldxdw r0, [r2-16]
1749 exit
1750 ",
1751 0xcd
1752 );
1753
1754 #[test]
test_cranelift_stack2()1755 fn test_cranelift_stack2() {
1756 let prog = assemble(
1757 "
1758 stb [r10-4], 0x01
1759 stb [r10-3], 0x02
1760 stb [r10-2], 0x03
1761 stb [r10-1], 0x04
1762 mov r1, r10
1763 mov r2, 0x4
1764 sub r1, r2
1765 call 1
1766 mov r1, 0
1767 ldxb r2, [r10-4]
1768 ldxb r3, [r10-3]
1769 ldxb r4, [r10-2]
1770 ldxb r5, [r10-1]
1771 call 0
1772 xor r0, 0x2a2a2a2a
1773 exit",
1774 )
1775 .unwrap();
1776
1777 let mut vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1778 vm.register_helper(0, helpers::gather_bytes).unwrap();
1779 vm.register_helper(1, helpers::memfrob).unwrap();
1780 vm.cranelift_compile().unwrap();
1781 assert_eq!(vm.execute_program_cranelift().unwrap(), 0x01020304);
1782 }
1783
1784 test_cranelift!(
1785 test_cranelift_stb,
1786 "
1787 stb [r1+2], 0x11
1788 ldxb r0, [r1+2]
1789 exit
1790 ",
1791 [0xaa, 0xbb, 0xff, 0xcc, 0xdd],
1792 0x11
1793 );
1794
1795 test_cranelift!(
1796 test_cranelift_stdw,
1797 "
1798 stdw [r1+2], 0x44332211
1799 ldxdw r0, [r1+2]
1800 exit
1801 ",
1802 [0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd],
1803 0x44332211
1804 );
1805
1806 test_cranelift!(
1807 test_cranelift_sth,
1808 "
1809 sth [r1+2], 0x2211
1810 ldxh r0, [r1+2]
1811 exit
1812 ",
1813 [0xaa, 0xbb, 0xff, 0xff, 0xcc, 0xdd],
1814 0x2211
1815 );
1816
1817 #[test]
1818 #[ignore]
test_cranelift_string_stack()1819 fn test_cranelift_string_stack() {
1820 let prog = assemble(
1821 "
1822 mov r1, 0x78636261
1823 stxw [r10-8], r1
1824 mov r6, 0x0
1825 stxb [r10-4], r6
1826 stxb [r10-12], r6
1827 mov r1, 0x79636261
1828 stxw [r10-16], r1
1829 mov r1, r10
1830 add r1, -8
1831 mov r2, r1
1832 call 0x4
1833 mov r1, r0
1834 mov r0, 0x1
1835 lsh r1, 0x20
1836 rsh r1, 0x20
1837 jne r1, 0x0, +11
1838 mov r1, r10
1839 add r1, -8
1840 mov r2, r10
1841 add r2, -16
1842 call 0x4
1843 mov r1, r0
1844 lsh r1, 0x20
1845 rsh r1, 0x20
1846 mov r0, 0x1
1847 jeq r1, r6, +1
1848 mov r0, 0x0
1849 exit",
1850 )
1851 .unwrap();
1852
1853 let mut vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1854 vm.register_helper(4, helpers::strcmp).unwrap();
1855 vm.cranelift_compile().unwrap();
1856 assert_eq!(vm.execute_program_cranelift().unwrap(), 0x0);
1857 }
1858
1859 test_cranelift!(
1860 test_cranelift_stw,
1861 "
1862 stw [r1+2], 0x44332211
1863 ldxw r0, [r1+2]
1864 exit
1865 ",
1866 [0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd],
1867 0x44332211
1868 );
1869
1870 test_cranelift!(
1871 test_cranelift_stxb,
1872 "
1873 mov32 r2, 0x11
1874 stxb [r1+2], r2
1875 ldxb r0, [r1+2]
1876 exit
1877 ",
1878 [0xaa, 0xbb, 0xff, 0xcc, 0xdd],
1879 0x11
1880 );
1881
1882 test_cranelift!(
1883 test_cranelift_stxb_all,
1884 "
1885 mov r0, 0xf0
1886 mov r2, 0xf2
1887 mov r3, 0xf3
1888 mov r4, 0xf4
1889 mov r5, 0xf5
1890 mov r6, 0xf6
1891 mov r7, 0xf7
1892 mov r8, 0xf8
1893 stxb [r1], r0
1894 stxb [r1+1], r2
1895 stxb [r1+2], r3
1896 stxb [r1+3], r4
1897 stxb [r1+4], r5
1898 stxb [r1+5], r6
1899 stxb [r1+6], r7
1900 stxb [r1+7], r8
1901 ldxdw r0, [r1]
1902 be64 r0
1903 exit
1904 ",
1905 [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
1906 0xf0f2f3f4f5f6f7f8
1907 );
1908
1909 test_cranelift!(
1910 test_cranelift_stxb_all2,
1911 "
1912 mov r0, r1
1913 mov r1, 0xf1
1914 mov r9, 0xf9
1915 stxb [r0], r1
1916 stxb [r0+1], r9
1917 ldxh r0, [r0]
1918 be16 r0
1919 exit
1920 ",
1921 [0xff, 0xff],
1922 0xf1f9
1923 );
1924
1925 test_cranelift!(
1926 test_cranelift_stxb_chain,
1927 "
1928 mov r0, r1
1929 ldxb r9, [r0+0]
1930 stxb [r0+1], r9
1931 ldxb r8, [r0+1]
1932 stxb [r0+2], r8
1933 ldxb r7, [r0+2]
1934 stxb [r0+3], r7
1935 ldxb r6, [r0+3]
1936 stxb [r0+4], r6
1937 ldxb r5, [r0+4]
1938 stxb [r0+5], r5
1939 ldxb r4, [r0+5]
1940 stxb [r0+6], r4
1941 ldxb r3, [r0+6]
1942 stxb [r0+7], r3
1943 ldxb r2, [r0+7]
1944 stxb [r0+8], r2
1945 ldxb r1, [r0+8]
1946 stxb [r0+9], r1
1947 ldxb r0, [r0+9]
1948 exit
1949 ",
1950 [0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
1951 0x2a
1952 );
1953
1954 test_cranelift!(
1955 test_cranelift_stxdw,
1956 "
1957 mov r2, -2005440939
1958 lsh r2, 32
1959 or r2, 0x44332211
1960 stxdw [r1+2], r2
1961 ldxdw r0, [r1+2]
1962 exit
1963 ",
1964 [0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd],
1965 0x8877665544332211
1966 );
1967
1968 test_cranelift!(
1969 test_cranelift_stxh,
1970 "
1971 mov32 r2, 0x2211
1972 stxh [r1+2], r2
1973 ldxh r0, [r1+2]
1974 exit
1975 ",
1976 [0xaa, 0xbb, 0xff, 0xff, 0xcc, 0xdd],
1977 0x2211
1978 );
1979
1980 test_cranelift!(
1981 test_cranelift_stxw,
1982 "
1983 mov32 r2, 0x44332211
1984 stxw [r1+2], r2
1985 ldxw r0, [r1+2]
1986 exit
1987 ",
1988 [0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd],
1989 0x44332211
1990 );
1991
1992 test_cranelift!(
1993 test_cranelift_subnet,
1994 "
1995 mov r2, 0xe
1996 ldxh r3, [r1+12]
1997 jne r3, 0x81, +2
1998 mov r2, 0x12
1999 ldxh r3, [r1+16]
2000 and r3, 0xffff
2001 jne r3, 0x8, +5
2002 add r1, r2
2003 mov r0, 0x1
2004 ldxw r1, [r1+16]
2005 and r1, 0xffffff
2006 jeq r1, 0x1a8c0, +1
2007 mov r0, 0x0
2008 exit
2009 ",
2010 [
2011 0x00, 0x00, 0xc0, 0x9f, 0xa0, 0x97, 0x00, 0xa0, 0xcc, 0x3b, 0xbf, 0xfa, 0x08, 0x00, 0x45,
2012 0x10, 0x00, 0x3c, 0x46, 0x3c, 0x40, 0x00, 0x40, 0x06, 0x73, 0x1c, 0xc0, 0xa8, 0x01, 0x02,
2013 0xc0, 0xa8, 0x01, 0x01, 0x06, 0x0e, 0x00, 0x17, 0x99, 0xc5, 0xa0, 0xec, 0x00, 0x00, 0x00,
2014 0x00, 0xa0, 0x02, 0x7d, 0x78, 0xe0, 0xa3, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, 0x04, 0x02,
2015 0x08, 0x0a, 0x00, 0x9c, 0x27, 0x24, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x00,
2016 ],
2017 0x1
2018 );
2019
2020 const PROG_TCP_PORT_80: [u8; 152] = [
2021 0x71, 0x12, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x13, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
2022 0x67, 0x03, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2023 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x0c, 0x00, 0x08, 0x00, 0x00, 0x00,
2024 0x71, 0x12, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x02, 0x0a, 0x00, 0x06, 0x00, 0x00, 0x00,
2025 0x71, 0x12, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x01, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
2026 0x57, 0x02, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x67, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
2027 0x0f, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
2028 0x15, 0x02, 0x02, 0x00, 0x00, 0x50, 0x00, 0x00, 0x69, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2029 0x55, 0x01, 0x01, 0x00, 0x00, 0x50, 0x00, 0x00, 0xb7, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
2030 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2031 ];
2032
2033 #[test]
test_cranelift_tcp_port80_match()2034 fn test_cranelift_tcp_port80_match() {
2035 let mem = &mut [
2036 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x08, 0x00, 0x45,
2037 0x00, 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01,
2038 0xc0, 0xa8, 0x00, 0x02, 0x27, 0x10, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2039 0x00, 0x50, 0x02, 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2040 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2041 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2042 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2043 ];
2044 let prog = &PROG_TCP_PORT_80;
2045 let mut vm = rbpf::EbpfVmRaw::new(Some(prog)).unwrap();
2046 vm.cranelift_compile().unwrap();
2047 assert_eq!(vm.execute_program_cranelift(mem).unwrap(), 0x1);
2048 }
2049
2050 #[test]
test_cranelift_tcp_port80_nomatch()2051 fn test_cranelift_tcp_port80_nomatch() {
2052 let mem = &mut [
2053 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x08, 0x00, 0x45,
2054 0x00, 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01,
2055 0xc0, 0xa8, 0x00, 0x02, 0x00, 0x16, 0x27, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2056 0x00, 0x51, 0x02, 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2057 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2058 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2059 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2060 ];
2061 let prog = &PROG_TCP_PORT_80;
2062 let mut vm = rbpf::EbpfVmRaw::new(Some(prog)).unwrap();
2063 vm.cranelift_compile().unwrap();
2064 assert_eq!(vm.execute_program_cranelift(mem).unwrap(), 0x0);
2065 }
2066
2067 #[test]
test_cranelift_tcp_port80_nomatch_ethertype()2068 fn test_cranelift_tcp_port80_nomatch_ethertype() {
2069 let mem = &mut [
2070 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x08, 0x01, 0x45,
2071 0x00, 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01,
2072 0xc0, 0xa8, 0x00, 0x02, 0x27, 0x10, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2073 0x00, 0x50, 0x02, 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2074 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2075 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2076 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2077 ];
2078 let prog = &PROG_TCP_PORT_80;
2079 let mut vm = rbpf::EbpfVmRaw::new(Some(prog)).unwrap();
2080 vm.cranelift_compile().unwrap();
2081 assert_eq!(vm.execute_program_cranelift(mem).unwrap(), 0x0);
2082 }
2083
2084 #[test]
test_cranelift_tcp_port80_nomatch_proto()2085 fn test_cranelift_tcp_port80_nomatch_proto() {
2086 let mem = &mut [
2087 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x08, 0x00, 0x45,
2088 0x00, 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x11, 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01,
2089 0xc0, 0xa8, 0x00, 0x02, 0x27, 0x10, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2090 0x00, 0x50, 0x02, 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2091 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2092 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2093 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2094 ];
2095 let prog = &PROG_TCP_PORT_80;
2096 let mut vm = rbpf::EbpfVmRaw::new(Some(prog)).unwrap();
2097 vm.cranelift_compile().unwrap();
2098 assert_eq!(vm.execute_program_cranelift(mem).unwrap(), 0x0);
2099 }
2100
2101 #[test]
test_cranelift_tcp_sack_match()2102 fn test_cranelift_tcp_sack_match() {
2103 let mut mem = TCP_SACK_MATCH.to_vec();
2104 let prog = assemble(TCP_SACK_ASM).unwrap();
2105 let mut vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
2106 vm.cranelift_compile().unwrap();
2107 assert_eq!(
2108 vm.execute_program_cranelift(mem.as_mut_slice()).unwrap(),
2109 0x1
2110 );
2111 }
2112
2113 #[test]
test_cranelift_tcp_sack_nomatch()2114 fn test_cranelift_tcp_sack_nomatch() {
2115 let mut mem = TCP_SACK_NOMATCH.to_vec();
2116 let prog = assemble(TCP_SACK_ASM).unwrap();
2117 let mut vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
2118 vm.cranelift_compile().unwrap();
2119 assert_eq!(
2120 vm.execute_program_cranelift(mem.as_mut_slice()).unwrap(),
2121 0x0
2122 );
2123 }
2124
2125 #[test]
test_cranelift_ldabsb()2126 fn test_cranelift_ldabsb() {
2127 let prog = &[
2128 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2129 0x00,
2130 ];
2131 let mem = &mut [
2132 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
2133 0xff,
2134 ];
2135 let mut vm = rbpf::EbpfVmFixedMbuff::new(Some(prog), 0x00, 0x08).unwrap();
2136
2137 vm.cranelift_compile().unwrap();
2138 assert_eq!(vm.execute_program_cranelift(mem).unwrap(), 0x33);
2139 }
2140
2141 #[test]
test_cranelift_ldabsh()2142 fn test_cranelift_ldabsh() {
2143 let prog = &[
2144 0x28, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2145 0x00,
2146 ];
2147 let mem = &mut [
2148 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
2149 0xff,
2150 ];
2151 let mut vm = rbpf::EbpfVmFixedMbuff::new(Some(prog), 0x00, 0x08).unwrap();
2152
2153 vm.cranelift_compile().unwrap();
2154 assert_eq!(vm.execute_program_cranelift(mem).unwrap(), 0x4433);
2155 }
2156
2157 #[test]
test_cranelift_ldabsw()2158 fn test_cranelift_ldabsw() {
2159 let prog = &[
2160 0x20, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2161 0x00,
2162 ];
2163 let mem = &mut [
2164 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
2165 0xff,
2166 ];
2167 let mut vm = rbpf::EbpfVmFixedMbuff::new(Some(prog), 0x00, 0x08).unwrap();
2168
2169 vm.cranelift_compile().unwrap();
2170 assert_eq!(vm.execute_program_cranelift(mem).unwrap(), 0x66554433);
2171 }
2172
2173 #[test]
test_cranelift_ldabsdw()2174 fn test_cranelift_ldabsdw() {
2175 let prog = &[
2176 0x38, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2177 0x00,
2178 ];
2179 let mem = &mut [
2180 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
2181 0xff,
2182 ];
2183 let mut vm = rbpf::EbpfVmFixedMbuff::new(Some(prog), 0x00, 0x08).unwrap();
2184
2185 vm.cranelift_compile().unwrap();
2186 assert_eq!(
2187 vm.execute_program_cranelift(mem).unwrap(),
2188 0xaa99887766554433
2189 );
2190 }
2191
2192 #[test]
test_cranelift_ldindb()2193 fn test_cranelift_ldindb() {
2194 let prog = &[
2195 0xb7, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x50, 0x10, 0x00, 0x00, 0x03, 0x00, 0x00,
2196 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2197 ];
2198 let mem = &mut [
2199 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
2200 0xff,
2201 ];
2202 let mut vm = rbpf::EbpfVmFixedMbuff::new(Some(prog), 0x00, 0x08).unwrap();
2203
2204 vm.cranelift_compile().unwrap();
2205 assert_eq!(vm.execute_program_cranelift(mem).unwrap(), 0x88);
2206 }
2207
2208 #[test]
test_cranelift_ldindh()2209 fn test_cranelift_ldindh() {
2210 let prog = &[
2211 0xb7, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x48, 0x10, 0x00, 0x00, 0x03, 0x00, 0x00,
2212 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2213 ];
2214 let mem = &mut [
2215 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
2216 0xff,
2217 ];
2218 let mut vm = rbpf::EbpfVmFixedMbuff::new(Some(prog), 0x00, 0x08).unwrap();
2219
2220 vm.cranelift_compile().unwrap();
2221 assert_eq!(vm.execute_program_cranelift(mem).unwrap(), 0x9988);
2222 }
2223
2224 #[test]
test_cranelift_ldindw()2225 fn test_cranelift_ldindw() {
2226 let prog = &[
2227 0xb7, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00,
2228 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2229 ];
2230 let mem = &mut [
2231 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
2232 0xff,
2233 ];
2234 let mut vm = rbpf::EbpfVmFixedMbuff::new(Some(prog), 0x00, 0x08).unwrap();
2235
2236 vm.cranelift_compile().unwrap();
2237 assert_eq!(vm.execute_program_cranelift(mem).unwrap(), 0x88776655);
2238 }
2239
2240 #[test]
test_cranelift_ldinddw()2241 fn test_cranelift_ldinddw() {
2242 let prog = &[
2243 0xb7, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x58, 0x10, 0x00, 0x00, 0x03, 0x00, 0x00,
2244 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2245 ];
2246 let mem = &mut [
2247 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
2248 0xff,
2249 ];
2250 let mut vm = rbpf::EbpfVmFixedMbuff::new(Some(prog), 0x00, 0x08).unwrap();
2251
2252 vm.cranelift_compile().unwrap();
2253 assert_eq!(
2254 vm.execute_program_cranelift(mem).unwrap(),
2255 0xccbbaa9988776655
2256 );
2257 }
2258