xref: /DragonOS/kernel/crates/rbpf/tests/ubpf_vm.rs (revision fae6e9ade46a52976ad5d099643d51cc20876448)
1 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
2 // Converted from the tests for uBPF <https://github.com/iovisor/ubpf>
3 // Copyright 2015 Big Switch Networks, Inc
4 // Copyright 2016 6WIND S.A. <quentin.monnet@6wind.com>
5 
6 // The tests contained in this file are extracted from the unit tests of uBPF software. Each test
7 // in this file has a name in the form `test_vm_<name>`, and corresponds to the (human-readable)
8 // code in `ubpf/tree/master/tests/<name>`, available at
9 // <https://github.com/iovisor/ubpf/tree/master/tests> (hyphen had to be replaced with underscores
10 // as Rust will not accept them in function names). It is strongly advised to refer to the uBPF
11 // version to understand what these program do.
12 //
13 // Each program was assembled from the uBPF version with the assembler provided by uBPF itself, and
14 // available at <https://github.com/iovisor/ubpf/tree/master/ubpf>.
15 // The very few modifications that have been realized should be indicated.
16 
17 // These are unit tests for the eBPF interpreter.
18 
19 #![allow(clippy::unreadable_literal)]
20 
21 extern crate rbpf;
22 mod common;
23 
24 use common::{TCP_SACK_ASM, TCP_SACK_MATCH, TCP_SACK_NOMATCH};
25 use rbpf::{assembler::assemble, helpers};
26 
27 #[test]
28 fn test_vm_add() {
29     let prog = assemble(
30         "
31         mov32 r0, 0
32         mov32 r1, 2
33         add32 r0, 1
34         add32 r0, r1
35         exit",
36     )
37     .unwrap();
38     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
39     assert_eq!(vm.execute_program().unwrap(), 0x3);
40 }
41 
42 #[test]
43 fn test_vm_alu64_arith() {
44     let prog = assemble(
45         "
46         mov r0, 0
47         mov r1, 1
48         mov r2, 2
49         mov r3, 3
50         mov r4, 4
51         mov r5, 5
52         mov r6, 6
53         mov r7, 7
54         mov r8, 8
55         mov r9, 9
56         add r0, 23
57         add r0, r7
58         sub r0, 13
59         sub r0, r1
60         mul r0, 7
61         mul r0, r3
62         div r0, 2
63         div r0, r4
64         exit",
65     )
66     .unwrap();
67     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
68     assert_eq!(vm.execute_program().unwrap(), 0x2a);
69 }
70 
71 #[test]
72 fn test_vm_alu64_bit() {
73     let prog = assemble(
74         "
75         mov r0, 0
76         mov r1, 1
77         mov r2, 2
78         mov r3, 3
79         mov r4, 4
80         mov r5, 5
81         mov r6, 6
82         mov r7, 7
83         mov r8, 8
84         or r0, r5
85         or r0, 0xa0
86         and r0, 0xa3
87         mov r9, 0x91
88         and r0, r9
89         lsh r0, 32
90         lsh r0, 22
91         lsh r0, r8
92         rsh r0, 32
93         rsh r0, 19
94         rsh r0, r7
95         xor r0, 0x03
96         xor r0, r2
97         exit",
98     )
99     .unwrap();
100     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
101     assert_eq!(vm.execute_program().unwrap(), 0x11);
102 }
103 
104 #[test]
105 fn test_vm_alu_arith() {
106     let prog = assemble(
107         "
108         mov32 r0, 0
109         mov32 r1, 1
110         mov32 r2, 2
111         mov32 r3, 3
112         mov32 r4, 4
113         mov32 r5, 5
114         mov32 r6, 6
115         mov32 r7, 7
116         mov32 r8, 8
117         mov32 r9, 9
118         add32 r0, 23
119         add32 r0, r7
120         sub32 r0, 13
121         sub32 r0, r1
122         mul32 r0, 7
123         mul32 r0, r3
124         div32 r0, 2
125         div32 r0, r4
126         exit",
127     )
128     .unwrap();
129     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
130     assert_eq!(vm.execute_program().unwrap(), 0x2a);
131 }
132 
133 #[test]
134 fn test_vm_alu_bit() {
135     let prog = assemble(
136         "
137         mov32 r0, 0
138         mov32 r1, 1
139         mov32 r2, 2
140         mov32 r3, 3
141         mov32 r4, 4
142         mov32 r5, 5
143         mov32 r6, 6
144         mov32 r7, 7
145         mov32 r8, 8
146         or32 r0, r5
147         or32 r0, 0xa0
148         and32 r0, 0xa3
149         mov32 r9, 0x91
150         and32 r0, r9
151         lsh32 r0, 22
152         lsh32 r0, r8
153         rsh32 r0, 19
154         rsh32 r0, r7
155         xor32 r0, 0x03
156         xor32 r0, r2
157         exit",
158     )
159     .unwrap();
160     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
161     assert_eq!(vm.execute_program().unwrap(), 0x11);
162 }
163 
164 #[test]
165 fn test_vm_arsh32_high_shift() {
166     let prog = assemble(
167         "
168         mov r0, 8
169         lddw r1, 0x100000001
170         arsh32 r0, r1
171         exit",
172     )
173     .unwrap();
174     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
175     assert_eq!(vm.execute_program().unwrap(), 0x4);
176 }
177 
178 #[test]
179 fn test_vm_arsh() {
180     let prog = assemble(
181         "
182         mov32 r0, 0xf8
183         lsh32 r0, 28
184         arsh32 r0, 16
185         exit",
186     )
187     .unwrap();
188     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
189     assert_eq!(vm.execute_program().unwrap(), 0xffff8000);
190 }
191 
192 #[test]
193 fn test_vm_arsh64() {
194     let prog = assemble(
195         "
196         mov32 r0, 1
197         lsh r0, 63
198         arsh r0, 55
199         mov32 r1, 5
200         arsh r0, r1
201         exit",
202     )
203     .unwrap();
204     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
205     assert_eq!(vm.execute_program().unwrap(), 0xfffffffffffffff8);
206 }
207 
208 #[test]
209 fn test_vm_arsh_reg() {
210     let prog = assemble(
211         "
212         mov32 r0, 0xf8
213         mov32 r1, 16
214         lsh32 r0, 28
215         arsh32 r0, r1
216         exit",
217     )
218     .unwrap();
219     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
220     assert_eq!(vm.execute_program().unwrap(), 0xffff8000);
221 }
222 
223 #[test]
224 fn test_vm_arsh_imm_overflow() {
225     let prog = assemble(
226         "
227         mov r0, 1
228         lsh r0, 63
229         arsh r0, 0xff20
230         exit",
231     )
232     .unwrap();
233     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
234     assert_eq!(vm.execute_program().unwrap(), 0xffffffff80000000);
235 }
236 
237 #[test]
238 fn test_vm_arsh_reg_overflow() {
239     let prog = assemble(
240         "
241         mov r0, 1
242         lsh r0, 63
243         mov r1, 0xff04
244         arsh r0, r1
245         exit",
246     )
247     .unwrap();
248     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
249     assert_eq!(vm.execute_program().unwrap(), 0xf800000000000000);
250 }
251 
252 #[test]
253 fn test_vm_arsh32_imm_overflow() {
254     let prog = assemble(
255         "
256         mov32 r0, 1
257         lsh32 r0, 31
258         arsh32 r0, 0xff10
259         exit",
260     )
261     .unwrap();
262     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
263     assert_eq!(vm.execute_program().unwrap(), 0xffff8000);
264 }
265 
266 #[test]
267 fn test_vm_arsh32_reg_overflow() {
268     let prog = assemble(
269         "
270         mov32 r0, 1
271         lsh32 r0, 31
272         mov32 r1, 32
273         arsh32 r0, r1
274         exit",
275     )
276     .unwrap();
277     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
278     assert_eq!(vm.execute_program().unwrap(), 0x80000000);
279 }
280 
281 #[test]
282 fn test_vm_be16() {
283     let prog = assemble(
284         "
285         ldxh r0, [r1]
286         be16 r0
287         exit",
288     )
289     .unwrap();
290     let mem = &mut [0x11, 0x22];
291     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
292     assert_eq!(vm.execute_program(mem).unwrap(), 0x1122);
293 }
294 
295 #[test]
296 fn test_vm_be16_high() {
297     let prog = assemble(
298         "
299         ldxdw r0, [r1]
300         be16 r0
301         exit",
302     )
303     .unwrap();
304     let mem = &mut [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88];
305     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
306     assert_eq!(vm.execute_program(mem).unwrap(), 0x1122);
307 }
308 
309 #[test]
310 fn test_vm_be32() {
311     let prog = assemble(
312         "
313         ldxw r0, [r1]
314         be32 r0
315         exit",
316     )
317     .unwrap();
318     let mem = &mut [0x11, 0x22, 0x33, 0x44];
319     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
320     assert_eq!(vm.execute_program(mem).unwrap(), 0x11223344);
321 }
322 
323 #[test]
324 fn test_vm_be32_high() {
325     let prog = assemble(
326         "
327         ldxdw r0, [r1]
328         be32 r0
329         exit",
330     )
331     .unwrap();
332     let mem = &mut [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88];
333     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
334     assert_eq!(vm.execute_program(mem).unwrap(), 0x11223344);
335 }
336 
337 #[test]
338 fn test_vm_be64() {
339     let prog = assemble(
340         "
341         ldxdw r0, [r1]
342         be64 r0
343         exit",
344     )
345     .unwrap();
346     let mem = &mut [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88];
347     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
348     assert_eq!(vm.execute_program(mem).unwrap(), 0x1122334455667788);
349 }
350 
351 #[test]
352 fn test_vm_call() {
353     let prog = assemble(
354         "
355         mov r1, 1
356         mov r2, 2
357         mov r3, 3
358         mov r4, 4
359         mov r5, 5
360         call 0
361         exit",
362     )
363     .unwrap();
364     let mut vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
365     vm.register_helper(0, helpers::gather_bytes).unwrap();
366     assert_eq!(vm.execute_program().unwrap(), 0x0102030405);
367 }
368 
369 #[test]
370 fn test_vm_call_memfrob() {
371     let prog = assemble(
372         "
373         mov r6, r1
374         add r1, 2
375         mov r2, 4
376         call 1
377         ldxdw r0, [r6]
378         be64 r0
379         exit",
380     )
381     .unwrap();
382     let mem = &mut [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];
383     let mut vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
384     vm.register_helper(1, helpers::memfrob).unwrap();
385     assert_eq!(vm.execute_program(mem).unwrap(), 0x102292e2f2c0708);
386 }
387 
388 // TODO: helpers::trash_registers needs asm!().
389 // Try this again once asm!() is available in stable.
390 //#[test]
391 //fn test_vm_call_save() {
392 //let prog = &[
393 //0xb7, 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
394 //0xb7, 0x07, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
395 //0xb7, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
396 //0xb7, 0x09, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
397 //0x85, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
398 //0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399 //0x4f, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
400 //0x4f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401 //0x4f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
402 //0x4f, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
403 //0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
404 //];
405 //let mut vm = rbpf::EbpfVmNoData::new(Some(prog)).unwrap();
406 //vm.register_helper(2, helpers::trash_registers);
407 //assert_eq!(vm.execute_program().unwrap(), 0x4321);
408 //}
409 
410 #[test]
411 fn test_vm_div32_high_divisor() {
412     let prog = assemble(
413         "
414         mov r0, 12
415         lddw r1, 0x100000004
416         div32 r0, r1
417         exit",
418     )
419     .unwrap();
420     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
421     assert_eq!(vm.execute_program().unwrap(), 0x3);
422 }
423 
424 #[test]
425 fn test_vm_div32_imm() {
426     let prog = assemble(
427         "
428         lddw r0, 0x10000000c
429         div32 r0, 4
430         exit",
431     )
432     .unwrap();
433     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
434     assert_eq!(vm.execute_program().unwrap(), 0x3);
435 }
436 
437 #[test]
438 fn test_vm_div32_reg() {
439     let prog = assemble(
440         "
441         lddw r0, 0x10000000c
442         mov r1, 4
443         div32 r0, r1
444         exit",
445     )
446     .unwrap();
447     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
448     assert_eq!(vm.execute_program().unwrap(), 0x3);
449 }
450 
451 #[test]
452 fn test_vm_div64_imm() {
453     let prog = assemble(
454         "
455         mov r0, 0xc
456         lsh r0, 32
457         div r0, 4
458         exit",
459     )
460     .unwrap();
461     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
462     assert_eq!(vm.execute_program().unwrap(), 0x300000000);
463 }
464 
465 #[test]
466 fn test_vm_div64_reg() {
467     let prog = assemble(
468         "
469         mov r0, 0xc
470         lsh r0, 32
471         mov r1, 4
472         div r0, r1
473         exit",
474     )
475     .unwrap();
476     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
477     assert_eq!(vm.execute_program().unwrap(), 0x300000000);
478 }
479 
480 #[test]
481 fn test_vm_early_exit() {
482     let prog = assemble(
483         "
484         mov r0, 3
485         exit
486         mov r0, 4
487         exit",
488     )
489     .unwrap();
490     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
491     assert_eq!(vm.execute_program().unwrap(), 0x3);
492 }
493 
494 // uBPF limits the number of user functions at 64. We don't.
495 //#[test]
496 //fn test_vm_err_call_bad_imm() {
497 //}
498 
499 #[test]
500 #[should_panic(expected = "Error: unknown helper function (id: 0x3f)")]
501 fn test_vm_err_call_unreg() {
502     let prog = assemble(
503         "
504         mov r1, 1
505         mov r2, 2
506         mov r3, 3
507         mov r4, 4
508         mov r5, 5
509         call 63
510         exit",
511     )
512     .unwrap();
513     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
514     vm.execute_program().unwrap();
515 }
516 
517 #[test]
518 fn test_vm_div64_by_zero_imm() {
519     let prog = assemble(
520         "
521         mov32 r0, 1
522         div r0, 0
523         exit",
524     )
525     .unwrap();
526     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
527     assert_eq!(vm.execute_program().unwrap(), 0x0);
528 }
529 
530 #[test]
531 fn test_vm_div_by_zero_imm() {
532     let prog = assemble(
533         "
534         mov32 r0, 1
535         div32 r0, 0
536         exit",
537     )
538     .unwrap();
539     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
540     assert_eq!(vm.execute_program().unwrap(), 0x0);
541 }
542 
543 #[test]
544 fn test_vm_mod64_by_zero_imm() {
545     let prog = assemble(
546         "
547         mov32 r0, 1
548         mod r0, 0
549         exit",
550     )
551     .unwrap();
552     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
553     assert_eq!(vm.execute_program().unwrap(), 0x1);
554 }
555 
556 #[test]
557 fn test_vm_mod_by_zero_imm() {
558     let prog = assemble(
559         "
560         mov32 r0, 1
561         mod32 r0, 0
562         exit",
563     )
564     .unwrap();
565     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
566     assert_eq!(vm.execute_program().unwrap(), 0x1);
567 }
568 
569 // Make sure we only consider the last 32 bits of the divisor.
570 #[test]
571 fn test_vm_mod_by_zero_reg_long() {
572     let prog = assemble(
573         "
574         lddw r1, 0x100000000
575         mod32 r0, r1
576         exit",
577     )
578     .unwrap();
579     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
580     assert_eq!(vm.execute_program().unwrap(), 0x0);
581 }
582 
583 #[test]
584 fn test_vm_div64_by_zero_reg() {
585     let prog = assemble(
586         "
587         mov32 r0, 1
588         mov32 r1, 0
589         div r0, r1
590         exit",
591     )
592     .unwrap();
593     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
594     assert_eq!(vm.execute_program().unwrap(), 0x0);
595 }
596 
597 #[test]
598 fn test_vm_div_by_zero_reg() {
599     let prog = assemble(
600         "
601         mov32 r0, 1
602         mov32 r1, 0
603         div32 r0, r1
604         exit",
605     )
606     .unwrap();
607     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
608     assert_eq!(vm.execute_program().unwrap(), 0x0);
609 }
610 
611 // Make sure we only consider the last 32 bits of the divisor.
612 #[test]
613 fn test_vm_div_by_zero_reg_long() {
614     let prog = assemble(
615         "
616         lddw r1, 0x100000000
617         div32 r0, r1
618         exit",
619     )
620     .unwrap();
621     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
622     assert_eq!(vm.execute_program().unwrap(), 0x0);
623 }
624 
625 #[test]
626 fn test_vm_mod64_by_zero_reg() {
627     let prog = assemble(
628         "
629         mov32 r0, 1
630         mov32 r1, 0
631         mod r0, r1
632         exit",
633     )
634     .unwrap();
635     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
636     assert_eq!(vm.execute_program().unwrap(), 0x1);
637 }
638 
639 #[test]
640 fn test_vm_mod_by_zero_reg() {
641     let prog = assemble(
642         "
643         mov32 r0, 1
644         mov32 r1, 0
645         mod32 r0, r1
646         exit",
647     )
648     .unwrap();
649     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
650     assert_eq!(vm.execute_program().unwrap(), 0x1);
651 }
652 
653 #[test]
654 #[should_panic(expected = "Error: out of bounds memory store (insn #1)")]
655 fn test_vm_err_stack_out_of_bound() {
656     let prog = assemble(
657         "
658         stb [r10], 0
659         exit",
660     )
661     .unwrap();
662     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
663     vm.execute_program().unwrap();
664 }
665 
666 #[test]
667 fn test_vm_exit() {
668     let prog = assemble(
669         "
670         mov r0, 0
671         exit",
672     )
673     .unwrap();
674     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
675     assert_eq!(vm.execute_program().unwrap(), 0x0);
676 }
677 
678 #[test]
679 fn test_vm_ja() {
680     let prog = assemble(
681         "
682         mov r0, 1
683         ja +1
684         mov r0, 2
685         exit",
686     )
687     .unwrap();
688     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
689     assert_eq!(vm.execute_program().unwrap(), 0x1);
690 }
691 
692 #[test]
693 fn test_vm_jeq_imm() {
694     let prog = assemble(
695         "
696         mov32 r0, 0
697         mov32 r1, 0xa
698         jeq r1, 0xb, +4
699         mov32 r0, 1
700         mov32 r1, 0xb
701         jeq r1, 0xb, +1
702         mov32 r0, 2
703         exit",
704     )
705     .unwrap();
706     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
707     assert_eq!(vm.execute_program().unwrap(), 0x1);
708 }
709 
710 #[test]
711 fn test_vm_jeq_reg() {
712     let prog = assemble(
713         "
714         mov32 r0, 0
715         mov32 r1, 0xa
716         mov32 r2, 0xb
717         jeq r1, r2, +4
718         mov32 r0, 1
719         mov32 r1, 0xb
720         jeq r1, r2, +1
721         mov32 r0, 2
722         exit",
723     )
724     .unwrap();
725     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
726     assert_eq!(vm.execute_program().unwrap(), 0x1);
727 }
728 
729 #[test]
730 fn test_vm_jge_imm() {
731     let prog = assemble(
732         "
733         mov32 r0, 0
734         mov32 r1, 0xa
735         jge r1, 0xb, +4
736         mov32 r0, 1
737         mov32 r1, 0xc
738         jge r1, 0xb, +1
739         mov32 r0, 2
740         exit",
741     )
742     .unwrap();
743     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
744     assert_eq!(vm.execute_program().unwrap(), 0x1);
745 }
746 
747 #[test]
748 fn test_vm_jle_imm() {
749     let prog = assemble(
750         "
751         mov32 r0, 0
752         mov32 r1, 5
753         jle r1, 4, +1
754         jle r1, 6, +1
755         exit
756         jle r1, 5, +1
757         exit
758         mov32 r0, 1
759         exit",
760     )
761     .unwrap();
762     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
763     assert_eq!(vm.execute_program().unwrap(), 0x1);
764 }
765 
766 #[test]
767 fn test_vm_jle_reg() {
768     let prog = assemble(
769         "
770         mov r0, 0
771         mov r1, 5
772         mov r2, 4
773         mov r3, 6
774         jle r1, r2, +2
775         jle r1, r1, +1
776         exit
777         jle r1, r3, +1
778         exit
779         mov r0, 1
780         exit",
781     )
782     .unwrap();
783     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
784     assert_eq!(vm.execute_program().unwrap(), 0x1);
785 }
786 
787 #[test]
788 fn test_vm_jgt_imm() {
789     let prog = assemble(
790         "
791         mov32 r0, 0
792         mov32 r1, 5
793         jgt r1, 6, +2
794         jgt r1, 5, +1
795         jgt r1, 4, +1
796         exit
797         mov32 r0, 1
798         exit",
799     )
800     .unwrap();
801     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
802     assert_eq!(vm.execute_program().unwrap(), 0x1);
803 }
804 
805 #[test]
806 fn test_vm_jgt_reg() {
807     let prog = assemble(
808         "
809         mov r0, 0
810         mov r1, 5
811         mov r2, 6
812         mov r3, 4
813         jgt r1, r2, +2
814         jgt r1, r1, +1
815         jgt r1, r3, +1
816         exit
817         mov r0, 1
818         exit",
819     )
820     .unwrap();
821     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
822     assert_eq!(vm.execute_program().unwrap(), 0x1);
823 }
824 
825 #[test]
826 fn test_vm_jlt_imm() {
827     let prog = assemble(
828         "
829         mov32 r0, 0
830         mov32 r1, 5
831         jlt r1, 4, +2
832         jlt r1, 5, +1
833         jlt r1, 6, +1
834         exit
835         mov32 r0, 1
836         exit",
837     )
838     .unwrap();
839     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
840     assert_eq!(vm.execute_program().unwrap(), 0x1);
841 }
842 
843 #[test]
844 fn test_vm_jlt_reg() {
845     let prog = assemble(
846         "
847         mov r0, 0
848         mov r1, 5
849         mov r2, 4
850         mov r3, 6
851         jlt r1, r2, +2
852         jlt r1, r1, +1
853         jlt r1, r3, +1
854         exit
855         mov r0, 1
856         exit",
857     )
858     .unwrap();
859     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
860     assert_eq!(vm.execute_program().unwrap(), 0x1);
861 }
862 
863 #[test]
864 fn test_vm_jit_bounce() {
865     let prog = assemble(
866         "
867         mov r0, 1
868         mov r6, r0
869         mov r7, r6
870         mov r8, r7
871         mov r9, r8
872         mov r0, r9
873         exit",
874     )
875     .unwrap();
876     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
877     assert_eq!(vm.execute_program().unwrap(), 0x1);
878 }
879 
880 #[test]
881 fn test_vm_jne_reg() {
882     let prog = assemble(
883         "
884         mov32 r0, 0
885         mov32 r1, 0xb
886         mov32 r2, 0xb
887         jne r1, r2, +4
888         mov32 r0, 1
889         mov32 r1, 0xa
890         jne r1, r2, +1
891         mov32 r0, 2
892         exit",
893     )
894     .unwrap();
895     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
896     assert_eq!(vm.execute_program().unwrap(), 0x1);
897 }
898 
899 #[test]
900 fn test_vm_jset_imm() {
901     let prog = assemble(
902         "
903         mov32 r0, 0
904         mov32 r1, 0x7
905         jset r1, 0x8, +4
906         mov32 r0, 1
907         mov32 r1, 0x9
908         jset r1, 0x8, +1
909         mov32 r0, 2
910         exit",
911     )
912     .unwrap();
913     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
914     assert_eq!(vm.execute_program().unwrap(), 0x1);
915 }
916 
917 #[test]
918 fn test_vm_jset_reg() {
919     let prog = assemble(
920         "
921         mov32 r0, 0
922         mov32 r1, 0x7
923         mov32 r2, 0x8
924         jset r1, r2, +4
925         mov32 r0, 1
926         mov32 r1, 0x9
927         jset r1, r2, +1
928         mov32 r0, 2
929         exit",
930     )
931     .unwrap();
932     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
933     assert_eq!(vm.execute_program().unwrap(), 0x1);
934 }
935 
936 #[test]
937 fn test_vm_jsge_imm() {
938     let prog = assemble(
939         "
940         mov32 r0, 0
941         mov r1, -2
942         jsge r1, -1, +5
943         jsge r1, 0, +4
944         mov32 r0, 1
945         mov r1, -1
946         jsge r1, -1, +1
947         mov32 r0, 2
948         exit",
949     )
950     .unwrap();
951     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
952     assert_eq!(vm.execute_program().unwrap(), 0x1);
953 }
954 
955 #[test]
956 fn test_vm_jsge_reg() {
957     let prog = assemble(
958         "
959         mov32 r0, 0
960         mov r1, -2
961         mov r2, -1
962         mov32 r3, 0
963         jsge r1, r2, +5
964         jsge r1, r3, +4
965         mov32 r0, 1
966         mov r1, r2
967         jsge r1, r2, +1
968         mov32 r0, 2
969         exit",
970     )
971     .unwrap();
972     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
973     assert_eq!(vm.execute_program().unwrap(), 0x1);
974 }
975 
976 #[test]
977 fn test_vm_jsle_imm() {
978     let prog = assemble(
979         "
980         mov32 r0, 0
981         mov r1, -2
982         jsle r1, -3, +1
983         jsle r1, -1, +1
984         exit
985         mov32 r0, 1
986         jsle r1, -2, +1
987         mov32 r0, 2
988         exit",
989     )
990     .unwrap();
991     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
992     assert_eq!(vm.execute_program().unwrap(), 0x1);
993 }
994 
995 #[test]
996 fn test_vm_jsle_reg() {
997     let prog = assemble(
998         "
999         mov32 r0, 0
1000         mov r1, -1
1001         mov r2, -2
1002         mov32 r3, 0
1003         jsle r1, r2, +1
1004         jsle r1, r3, +1
1005         exit
1006         mov32 r0, 1
1007         mov r1, r2
1008         jsle r1, r2, +1
1009         mov32 r0, 2
1010         exit",
1011     )
1012     .unwrap();
1013     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1014     assert_eq!(vm.execute_program().unwrap(), 0x1);
1015 }
1016 
1017 #[test]
1018 fn test_vm_jsgt_imm() {
1019     let prog = assemble(
1020         "
1021         mov32 r0, 0
1022         mov r1, -2
1023         jsgt r1, -1, +4
1024         mov32 r0, 1
1025         mov32 r1, 0
1026         jsgt r1, -1, +1
1027         mov32 r0, 2
1028         exit",
1029     )
1030     .unwrap();
1031     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1032     assert_eq!(vm.execute_program().unwrap(), 0x1);
1033 }
1034 
1035 #[test]
1036 fn test_vm_jsgt_reg() {
1037     let prog = assemble(
1038         "
1039         mov32 r0, 0
1040         mov r1, -2
1041         mov r2, -1
1042         jsgt r1, r2, +4
1043         mov32 r0, 1
1044         mov32 r1, 0
1045         jsgt r1, r2, +1
1046         mov32 r0, 2
1047         exit",
1048     )
1049     .unwrap();
1050     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1051     assert_eq!(vm.execute_program().unwrap(), 0x1);
1052 }
1053 
1054 #[test]
1055 fn test_vm_jslt_imm() {
1056     let prog = assemble(
1057         "
1058         mov32 r0, 0
1059         mov r1, -2
1060         jslt r1, -3, +2
1061         jslt r1, -2, +1
1062         jslt r1, -1, +1
1063         exit
1064         mov32 r0, 1
1065         exit",
1066     )
1067     .unwrap();
1068     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1069     assert_eq!(vm.execute_program().unwrap(), 0x1);
1070 }
1071 
1072 #[test]
1073 fn test_vm_jslt_reg() {
1074     let prog = assemble(
1075         "
1076         mov32 r0, 0
1077         mov r1, -2
1078         mov r2, -3
1079         mov r3, -1
1080         jslt r1, r1, +2
1081         jslt r1, r2, +1
1082         jslt r1, r3, +1
1083         exit
1084         mov32 r0, 1
1085         exit",
1086     )
1087     .unwrap();
1088     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1089     assert_eq!(vm.execute_program().unwrap(), 0x1);
1090 }
1091 
1092 #[test]
1093 fn test_vm_jeq32_imm() {
1094     let prog = assemble(
1095         "
1096         mov r9, 1
1097         lsh r9, 32
1098         mov32 r0, 0x0
1099         mov32 r1, 0xa
1100         jeq32 r1, 0xb, +5
1101         mov32 r0, 1
1102         mov r1, 0xb
1103         or r1, r9
1104         jeq32 r1, 0xb, +1
1105         mov32 r0, 2
1106         exit",
1107     )
1108     .unwrap();
1109     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1110     assert_eq!(vm.execute_program().unwrap(), 0x1);
1111 }
1112 
1113 #[test]
1114 fn test_vm_jeq32_reg() {
1115     let prog = assemble(
1116         "
1117         mov r9, 1
1118         lsh r9, 32
1119         mov32 r0, 0
1120         mov32 r1, 0xa
1121         mov32 r2, 0xb
1122         jeq32 r1, r2, +5
1123         mov32 r0, 1
1124         mov32 r1, 0xb
1125         or r1, r9
1126         jeq32 r1, r2, +1
1127         mov32 r0, 2
1128         exit",
1129     )
1130     .unwrap();
1131     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1132     assert_eq!(vm.execute_program().unwrap(), 0x1);
1133 }
1134 
1135 #[test]
1136 fn test_vm_jge32_imm() {
1137     let prog = assemble(
1138         "
1139         mov r9, 1
1140         lsh r9, 32
1141         mov32 r0, 0
1142         mov32 r1, 0xa
1143         jge32 r1, 0xb, +5
1144         mov32 r0, 1
1145         or r1, r9
1146         mov32 r1, 0xc
1147         jge32 r1, 0xb, +1
1148         mov32 r0, 2
1149         exit",
1150     )
1151     .unwrap();
1152     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1153     assert_eq!(vm.execute_program().unwrap(), 0x1);
1154 }
1155 
1156 #[test]
1157 fn test_vm_jge32_reg() {
1158     let prog = assemble(
1159         "
1160         mov r9, 1
1161         lsh r9, 32
1162         mov32 r0, 0
1163         mov32 r1, 0xa
1164         mov32 r2, 0xb
1165         jge32 r1, r2, +5
1166         mov32 r0, 1
1167         or r1, r9
1168         mov32 r1, 0xc
1169         jge32 r1, r2, +1
1170         mov32 r0, 2
1171         exit",
1172     )
1173     .unwrap();
1174     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1175     assert_eq!(vm.execute_program().unwrap(), 0x1);
1176 }
1177 
1178 #[test]
1179 fn test_vm_jgt32_imm() {
1180     let prog = assemble(
1181         "
1182         mov r9, 1
1183         lsh r9, 32
1184         mov32 r0, 0
1185         mov32 r1, 5
1186         or r1, r9
1187         jgt32 r1, 6, +4
1188         jgt32 r1, 5, +3
1189         jgt32 r1, 4, +1
1190         exit
1191         mov32 r0, 1
1192         exit",
1193     )
1194     .unwrap();
1195     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1196     assert_eq!(vm.execute_program().unwrap(), 0x1);
1197 }
1198 
1199 #[test]
1200 fn test_vm_jgt32_reg() {
1201     let prog = assemble(
1202         "
1203         mov r9, 1
1204         lsh r9, 32
1205         mov r0, 0
1206         mov r1, 5
1207         mov32 r1, 5
1208         or r1, r9
1209         mov r2, 6
1210         mov r3, 4
1211         jgt32 r1, r2, +4
1212         jgt32 r1, r1, +3
1213         jgt32 r1, r3, +1
1214         exit
1215         mov r0, 1
1216         exit",
1217     )
1218     .unwrap();
1219     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1220     assert_eq!(vm.execute_program().unwrap(), 0x1);
1221 }
1222 
1223 #[test]
1224 fn test_vm_jle32_imm() {
1225     let prog = assemble(
1226         "
1227         mov r9, 1
1228         lsh r9, 32
1229         mov32 r0, 0
1230         mov32 r1, 5
1231         or r1, r9
1232         jle32 r1, 4, +5
1233         jle32 r1, 6, +1
1234         exit
1235         jle32 r1, 5, +1
1236         exit
1237         mov32 r0, 1
1238         exit",
1239     )
1240     .unwrap();
1241     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1242     assert_eq!(vm.execute_program().unwrap(), 0x1);
1243 }
1244 
1245 #[test]
1246 fn test_vm_jle32_reg() {
1247     let prog = assemble(
1248         "
1249         mov r9, 1
1250         lsh r9, 32
1251         mov r0, 0
1252         mov r1, 5
1253         mov r2, 4
1254         mov r3, 6
1255         or r1, r9
1256         jle32 r1, r2, +5
1257         jle32 r1, r1, +1
1258         exit
1259         jle32 r1, r3, +1
1260         exit
1261         mov r0, 1
1262         exit",
1263     )
1264     .unwrap();
1265     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1266     assert_eq!(vm.execute_program().unwrap(), 0x1);
1267 }
1268 
1269 #[test]
1270 fn test_vm_jlt32_imm() {
1271     let prog = assemble(
1272         "
1273         mov r9, 1
1274         lsh r9, 32
1275         mov32 r0, 0
1276         mov32 r1, 5
1277         or r1, r9
1278         jlt32 r1, 4, +4
1279         jlt32 r1, 5, +3
1280         jlt32 r1, 6, +1
1281         exit
1282         mov32 r0, 1
1283         exit",
1284     )
1285     .unwrap();
1286     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1287     assert_eq!(vm.execute_program().unwrap(), 0x1);
1288 }
1289 
1290 #[test]
1291 fn test_vm_jlt32_reg() {
1292     let prog = assemble(
1293         "
1294         mov r9, 1
1295         lsh r9, 32
1296         mov r0, 0
1297         mov r1, 5
1298         mov r2, 4
1299         mov r3, 6
1300         or r1, r9
1301         jlt32 r1, r2, +4
1302         jlt32 r1, r1, +3
1303         jlt32 r1, r3, +1
1304         exit
1305         mov r0, 1
1306         exit",
1307     )
1308     .unwrap();
1309     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1310     assert_eq!(vm.execute_program().unwrap(), 0x1);
1311 }
1312 
1313 #[test]
1314 fn test_vm_jne32_imm() {
1315     let prog = assemble(
1316         "
1317         mov r9, 1
1318         lsh r9, 32
1319         mov32 r0, 0
1320         mov32 r1, 0xb
1321         or r1, r9
1322         jne32 r1, 0xb, +4
1323         mov32 r0, 1
1324         mov32 r1, 0xa
1325         or r1, r9
1326         jne32 r1, 0xb, +1
1327         mov32 r0, 2
1328         exit",
1329     )
1330     .unwrap();
1331     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1332     assert_eq!(vm.execute_program().unwrap(), 0x1);
1333 }
1334 
1335 #[test]
1336 fn test_vm_jne32_reg() {
1337     let prog = assemble(
1338         "
1339         mov r9, 1
1340         lsh r9, 32
1341         mov32 r0, 0
1342         mov32 r1, 0xb
1343         or r1, r9
1344         mov32 r2, 0xb
1345         jne32 r1, r2, +4
1346         mov32 r0, 1
1347         mov32 r1, 0xa
1348         or r1, r9
1349         jne32 r1, r2, +1
1350         mov32 r0, 2
1351         exit",
1352     )
1353     .unwrap();
1354     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1355     assert_eq!(vm.execute_program().unwrap(), 0x1);
1356 }
1357 
1358 #[test]
1359 fn test_vm_jset32_imm() {
1360     let prog = assemble(
1361         "
1362         mov r9, 1
1363         lsh r9, 32
1364         mov32 r0, 0
1365         mov32 r1, 0x7
1366         or r1, r9
1367         jset32 r1, 0x8, +4
1368         mov32 r0, 1
1369         mov32 r1, 0x9
1370         jset32 r1, 0x8, +1
1371         mov32 r0, 2
1372         exit",
1373     )
1374     .unwrap();
1375     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1376     assert_eq!(vm.execute_program().unwrap(), 0x1);
1377 }
1378 
1379 #[test]
1380 fn test_vm_jset32_reg() {
1381     let prog = assemble(
1382         "
1383         mov r9, 1
1384         lsh r9, 32
1385         mov32 r0, 0
1386         mov32 r1, 0x7
1387         or r1, r9
1388         mov32 r2, 0x8
1389         jset32 r1, r2, +4
1390         mov32 r0, 1
1391         mov32 r1, 0x9
1392         jset32 r1, r2, +1
1393         mov32 r0, 2
1394         exit",
1395     )
1396     .unwrap();
1397     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1398     assert_eq!(vm.execute_program().unwrap(), 0x1);
1399 }
1400 
1401 #[test]
1402 fn test_vm_jsge32_imm() {
1403     let prog = assemble(
1404         "
1405         mov r9, 1
1406         lsh r9, 32
1407         mov32 r0, 0
1408         mov32 r1, -2
1409         or r1, r9
1410         jsge32 r1, -1, +5
1411         jsge32 r1, 0, +4
1412         mov32 r0, 1
1413         mov r1, -1
1414         jsge32 r1, -1, +1
1415         mov32 r0, 2
1416         exit",
1417     )
1418     .unwrap();
1419     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1420     assert_eq!(vm.execute_program().unwrap(), 0x1);
1421 }
1422 
1423 #[test]
1424 fn test_vm_jsge32_reg() {
1425     let prog = assemble(
1426         "
1427         mov r9, 1
1428         lsh r9, 32
1429         mov32 r0, 0
1430         mov32 r1, -2
1431         or r1, r9
1432         mov r2, -1
1433         mov32 r3, 0
1434         jsge32 r1, r2, +5
1435         jsge32 r1, r3, +4
1436         mov32 r0, 1
1437         mov r1, r2
1438         jsge32 r1, r2, +1
1439         mov32 r0, 2
1440         exit",
1441     )
1442     .unwrap();
1443     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1444     assert_eq!(vm.execute_program().unwrap(), 0x1);
1445 }
1446 
1447 #[test]
1448 fn test_vm_jsgt32_imm() {
1449     let prog = assemble(
1450         "
1451         mov r9, 1
1452         lsh r9, 32
1453         mov32 r0, 0
1454         mov32 r1, -2
1455         or r1, r9
1456         jsgt32 r1, -1, +4
1457         mov32 r0, 1
1458         mov32 r1, 0
1459         jsgt32 r1, -1, +1
1460         mov32 r0, 2
1461         exit",
1462     )
1463     .unwrap();
1464     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1465     assert_eq!(vm.execute_program().unwrap(), 0x1);
1466 }
1467 
1468 #[test]
1469 fn test_vm_jsgt32_reg() {
1470     let prog = assemble(
1471         "
1472         mov r9, 1
1473         lsh r9, 32
1474         mov32 r0, 0
1475         mov32 r1, -2
1476         or r1, r9
1477         mov r2, -1
1478         jsgt32 r1, r2, +4
1479         mov32 r0, 1
1480         mov32 r1, 0
1481         jsgt32 r1, r2, +1
1482         mov32 r0, 2
1483         exit",
1484     )
1485     .unwrap();
1486     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1487     assert_eq!(vm.execute_program().unwrap(), 0x1);
1488 }
1489 
1490 #[test]
1491 fn test_vm_jsle32_imm() {
1492     let prog = assemble(
1493         "
1494         mov r9, 1
1495         lsh r9, 32
1496         mov32 r0, 0
1497         mov32 r1, -2
1498         or r1, r9
1499         jsle32 r1, -3, +5
1500         jsle32 r1, -1, +1
1501         exit
1502         mov32 r0, 1
1503         jsle32 r1, -2, +1
1504         mov32 r0, 2
1505         exit",
1506     )
1507     .unwrap();
1508     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1509     assert_eq!(vm.execute_program().unwrap(), 0x1);
1510 }
1511 
1512 #[test]
1513 fn test_vm_jsle32_reg() {
1514     let prog = assemble(
1515         "
1516         mov r9, 1
1517         lsh r9, 32
1518         mov32 r0, 0
1519         mov32 r1, -2
1520         or r1, r9
1521         mov r2, -3
1522         mov32 r3, 0
1523         jsle32 r1, r2, +6
1524         jsle32 r1, r3, +1
1525         exit
1526         mov32 r0, 1
1527         mov r1, r2
1528         jsle32 r1, r2, +1
1529         mov32 r0, 2
1530         exit",
1531     )
1532     .unwrap();
1533     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1534     assert_eq!(vm.execute_program().unwrap(), 0x1);
1535 }
1536 
1537 #[test]
1538 fn test_vm_jslt32_imm() {
1539     let prog = assemble(
1540         "
1541         mov r9, 1
1542         lsh r9, 32
1543         mov32 r0, 0
1544         mov32 r1, -2
1545         or r1, r9
1546         jslt32 r1, -3, +4
1547         jslt32 r1, -2, +3
1548         jslt32 r1, -1, +1
1549         exit
1550         mov32 r0, 1
1551         exit",
1552     )
1553     .unwrap();
1554     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1555     assert_eq!(vm.execute_program().unwrap(), 0x1);
1556 }
1557 
1558 #[test]
1559 fn test_vm_jslt32_reg() {
1560     let prog = assemble(
1561         "
1562         mov r9, 1
1563         lsh r9, 32
1564         mov32 r0, 0
1565         mov32 r1, -2
1566         or r1, r9
1567         mov r2, -3
1568         mov r3, -1
1569         jslt32 r1, r1, +4
1570         jslt32 r1, r2, +3
1571         jslt32 r1, r3, +1
1572         exit
1573         mov32 r0, 1
1574         exit",
1575     )
1576     .unwrap();
1577     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1578     assert_eq!(vm.execute_program().unwrap(), 0x1);
1579 }
1580 
1581 #[test]
1582 fn test_vm_lddw() {
1583     let prog = assemble(
1584         "lddw r0, 0x1122334455667788
1585                          exit",
1586     )
1587     .unwrap();
1588     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1589     assert_eq!(vm.execute_program().unwrap(), 0x1122334455667788);
1590 }
1591 
1592 #[test]
1593 fn test_vm_lddw2() {
1594     let prog = assemble(
1595         "
1596         lddw r0, 0x0000000080000000
1597         exit",
1598     )
1599     .unwrap();
1600     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1601     assert_eq!(vm.execute_program().unwrap(), 0x80000000);
1602 }
1603 
1604 #[test]
1605 fn test_vm_ldxb_all() {
1606     let prog = assemble(
1607         "
1608         mov r0, r1
1609         ldxb r9, [r0+0]
1610         lsh r9, 0
1611         ldxb r8, [r0+1]
1612         lsh r8, 4
1613         ldxb r7, [r0+2]
1614         lsh r7, 8
1615         ldxb r6, [r0+3]
1616         lsh r6, 12
1617         ldxb r5, [r0+4]
1618         lsh r5, 16
1619         ldxb r4, [r0+5]
1620         lsh r4, 20
1621         ldxb r3, [r0+6]
1622         lsh r3, 24
1623         ldxb r2, [r0+7]
1624         lsh r2, 28
1625         ldxb r1, [r0+8]
1626         lsh r1, 32
1627         ldxb r0, [r0+9]
1628         lsh r0, 36
1629         or r0, r1
1630         or r0, r2
1631         or r0, r3
1632         or r0, r4
1633         or r0, r5
1634         or r0, r6
1635         or r0, r7
1636         or r0, r8
1637         or r0, r9
1638         exit",
1639     )
1640     .unwrap();
1641     let mem = &mut [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09];
1642     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
1643     assert_eq!(vm.execute_program(mem).unwrap(), 0x9876543210);
1644 }
1645 
1646 #[test]
1647 fn test_vm_ldxb() {
1648     let prog = assemble(
1649         "
1650         ldxb r0, [r1+2]
1651         exit",
1652     )
1653     .unwrap();
1654     let mem = &mut [0xaa, 0xbb, 0x11, 0xcc, 0xdd];
1655     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
1656     assert_eq!(vm.execute_program(mem).unwrap(), 0x11);
1657 }
1658 
1659 #[test]
1660 fn test_vm_ldxdw() {
1661     let prog = assemble(
1662         "
1663         ldxdw r0, [r1+2]
1664         exit",
1665     )
1666     .unwrap();
1667     let mem = &mut [
1668         0xaa, 0xbb, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0xcc, 0xdd,
1669     ];
1670     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
1671     assert_eq!(vm.execute_program(mem).unwrap(), 0x8877665544332211);
1672 }
1673 
1674 #[test]
1675 fn test_vm_ldxh_all() {
1676     let prog = assemble(
1677         "
1678         mov r0, r1
1679         ldxh r9, [r0+0]
1680         be16 r9
1681         lsh r9, 0
1682         ldxh r8, [r0+2]
1683         be16 r8
1684         lsh r8, 4
1685         ldxh r7, [r0+4]
1686         be16 r7
1687         lsh r7, 8
1688         ldxh r6, [r0+6]
1689         be16 r6
1690         lsh r6, 12
1691         ldxh r5, [r0+8]
1692         be16 r5
1693         lsh r5, 16
1694         ldxh r4, [r0+10]
1695         be16 r4
1696         lsh r4, 20
1697         ldxh r3, [r0+12]
1698         be16 r3
1699         lsh r3, 24
1700         ldxh r2, [r0+14]
1701         be16 r2
1702         lsh r2, 28
1703         ldxh r1, [r0+16]
1704         be16 r1
1705         lsh r1, 32
1706         ldxh r0, [r0+18]
1707         be16 r0
1708         lsh r0, 36
1709         or r0, r1
1710         or r0, r2
1711         or r0, r3
1712         or r0, r4
1713         or r0, r5
1714         or r0, r6
1715         or r0, r7
1716         or r0, r8
1717         or r0, r9
1718         exit",
1719     )
1720     .unwrap();
1721     let mem = &mut [
1722         0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00,
1723         0x07, 0x00, 0x08, 0x00, 0x09,
1724     ];
1725     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
1726     assert_eq!(vm.execute_program(mem).unwrap(), 0x9876543210);
1727 }
1728 
1729 #[test]
1730 fn test_vm_ldxh_all2() {
1731     let prog = assemble(
1732         "
1733         mov r0, r1
1734         ldxh r9, [r0+0]
1735         be16 r9
1736         ldxh r8, [r0+2]
1737         be16 r8
1738         ldxh r7, [r0+4]
1739         be16 r7
1740         ldxh r6, [r0+6]
1741         be16 r6
1742         ldxh r5, [r0+8]
1743         be16 r5
1744         ldxh r4, [r0+10]
1745         be16 r4
1746         ldxh r3, [r0+12]
1747         be16 r3
1748         ldxh r2, [r0+14]
1749         be16 r2
1750         ldxh r1, [r0+16]
1751         be16 r1
1752         ldxh r0, [r0+18]
1753         be16 r0
1754         or r0, r1
1755         or r0, r2
1756         or r0, r3
1757         or r0, r4
1758         or r0, r5
1759         or r0, r6
1760         or r0, r7
1761         or r0, r8
1762         or r0, r9
1763         exit",
1764     )
1765     .unwrap();
1766     let mem = &mut [
1767         0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00,
1768         0x80, 0x01, 0x00, 0x02, 0x00,
1769     ];
1770     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
1771     assert_eq!(vm.execute_program(mem).unwrap(), 0x3ff);
1772 }
1773 
1774 #[test]
1775 fn test_vm_ldxh() {
1776     let prog = assemble(
1777         "
1778         ldxh r0, [r1+2]
1779         exit",
1780     )
1781     .unwrap();
1782     let mem = &mut [0xaa, 0xbb, 0x11, 0x22, 0xcc, 0xdd];
1783     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
1784     assert_eq!(vm.execute_program(mem).unwrap(), 0x2211);
1785 }
1786 
1787 #[test]
1788 fn test_vm_ldxh_same_reg() {
1789     let prog = assemble(
1790         "
1791         mov r0, r1
1792         sth [r0], 0x1234
1793         ldxh r0, [r0]
1794         exit",
1795     )
1796     .unwrap();
1797     let mem = &mut [0xff, 0xff];
1798     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
1799     assert_eq!(vm.execute_program(mem).unwrap(), 0x1234);
1800 }
1801 
1802 #[test]
1803 fn test_vm_ldxw_all() {
1804     let prog = assemble(
1805         "
1806         mov r0, r1
1807         ldxw r9, [r0+0]
1808         be32 r9
1809         ldxw r8, [r0+4]
1810         be32 r8
1811         ldxw r7, [r0+8]
1812         be32 r7
1813         ldxw r6, [r0+12]
1814         be32 r6
1815         ldxw r5, [r0+16]
1816         be32 r5
1817         ldxw r4, [r0+20]
1818         be32 r4
1819         ldxw r3, [r0+24]
1820         be32 r3
1821         ldxw r2, [r0+28]
1822         be32 r2
1823         ldxw r1, [r0+32]
1824         be32 r1
1825         ldxw r0, [r0+36]
1826         be32 r0
1827         or r0, r1
1828         or r0, r2
1829         or r0, r3
1830         or r0, r4
1831         or r0, r5
1832         or r0, r6
1833         or r0, r7
1834         or r0, r8
1835         or r0, r9
1836         exit",
1837     )
1838     .unwrap();
1839     let mem = &mut [
1840         0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1841         0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1842         0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
1843     ];
1844     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
1845     assert_eq!(vm.execute_program(mem).unwrap(), 0x030f0f);
1846 }
1847 
1848 #[test]
1849 fn test_vm_ldxw() {
1850     let prog = assemble(
1851         "
1852         ldxw r0, [r1+2]
1853         exit",
1854     )
1855     .unwrap();
1856     let mem = &mut [0xaa, 0xbb, 0x11, 0x22, 0x33, 0x44, 0xcc, 0xdd];
1857     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
1858     assert_eq!(vm.execute_program(mem).unwrap(), 0x44332211);
1859 }
1860 
1861 #[test]
1862 fn test_vm_le16() {
1863     let prog = assemble(
1864         "
1865         ldxh r0, [r1]
1866         le16 r0
1867         exit",
1868     )
1869     .unwrap();
1870     let mem = &mut [0x22, 0x11];
1871     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
1872     assert_eq!(vm.execute_program(mem).unwrap(), 0x1122);
1873 }
1874 
1875 #[test]
1876 fn test_vm_le32() {
1877     let prog = assemble(
1878         "
1879         ldxw r0, [r1]
1880         le32 r0
1881         exit",
1882     )
1883     .unwrap();
1884     let mem = &mut [0x44, 0x33, 0x22, 0x11];
1885     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
1886     assert_eq!(vm.execute_program(mem).unwrap(), 0x11223344);
1887 }
1888 
1889 #[test]
1890 fn test_vm_le64() {
1891     let prog = assemble(
1892         "
1893         ldxdw r0, [r1]
1894         le64 r0
1895         exit",
1896     )
1897     .unwrap();
1898     let mem = &mut [0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11];
1899     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
1900     assert_eq!(vm.execute_program(mem).unwrap(), 0x1122334455667788);
1901 }
1902 
1903 #[test]
1904 fn test_vm_lsh_imm() {
1905     let prog = assemble(
1906         "
1907         mov r0, 1
1908         lsh r0, 4
1909         exit",
1910     )
1911     .unwrap();
1912     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1913     assert_eq!(vm.execute_program().unwrap(), 0x10);
1914 }
1915 
1916 #[test]
1917 fn test_vm_lsh_reg() {
1918     let prog = assemble(
1919         "
1920         mov r0, 1
1921         mov r7, 4
1922         lsh r0, r7
1923         exit",
1924     )
1925     .unwrap();
1926     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1927     assert_eq!(vm.execute_program().unwrap(), 0x10);
1928 }
1929 
1930 #[test]
1931 fn test_vm_lsh32_imm() {
1932     let prog = assemble(
1933         "
1934         mov32 r0, 1
1935         lsh32 r0, 4
1936         exit",
1937     )
1938     .unwrap();
1939     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1940     assert_eq!(vm.execute_program().unwrap(), 0x10);
1941 }
1942 
1943 #[test]
1944 fn test_vm_lsh32_reg() {
1945     let prog = assemble(
1946         "
1947         mov32 r0, 1
1948         mov32 r7, 4
1949         lsh32 r0, r7
1950         exit",
1951     )
1952     .unwrap();
1953     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1954     assert_eq!(vm.execute_program().unwrap(), 0x10);
1955 }
1956 
1957 #[test]
1958 fn test_vm_lsh_imm_overflow() {
1959     let prog = assemble(
1960         "
1961         mov r0, 1
1962         lsh r0, 64
1963         exit",
1964     )
1965     .unwrap();
1966     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1967     assert_eq!(vm.execute_program().unwrap(), 0x1);
1968 }
1969 
1970 #[test]
1971 fn test_vm_lsh_reg_overflow() {
1972     let prog = assemble(
1973         "
1974         mov r0, 1
1975         mov r7, 64
1976         lsh r0, r7
1977         exit",
1978     )
1979     .unwrap();
1980     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1981     assert_eq!(vm.execute_program().unwrap(), 0x1);
1982 }
1983 
1984 #[test]
1985 fn test_vm_lsh32_imm_overflow() {
1986     let prog = assemble(
1987         "
1988         mov32 r0, 1
1989         lsh32 r0, 32
1990         exit",
1991     )
1992     .unwrap();
1993     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1994     assert_eq!(vm.execute_program().unwrap(), 0x1);
1995 }
1996 
1997 #[test]
1998 fn test_vm_lsh32_reg_overflow() {
1999     let prog = assemble(
2000         "
2001         mov32 r0, 1
2002         mov32 r7, 32
2003         lsh32 r0, r7
2004         exit",
2005     )
2006     .unwrap();
2007     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
2008     assert_eq!(vm.execute_program().unwrap(), 0x1);
2009 }
2010 
2011 #[test]
2012 fn test_vm_mod() {
2013     let prog = assemble(
2014         "
2015         mov32 r0, 5748
2016         mod32 r0, 92
2017         mov32 r1, 13
2018         mod32 r0, r1
2019         exit",
2020     )
2021     .unwrap();
2022     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
2023     assert_eq!(vm.execute_program().unwrap(), 0x5);
2024 }
2025 
2026 #[test]
2027 fn test_vm_mod32() {
2028     let prog = assemble(
2029         "
2030         lddw r0, 0x100000003
2031         mod32 r0, 3
2032         exit",
2033     )
2034     .unwrap();
2035     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
2036     assert_eq!(vm.execute_program().unwrap(), 0x0);
2037 }
2038 
2039 #[test]
2040 fn test_vm_mod64() {
2041     let prog = assemble(
2042         "
2043         mov32 r0, -1316649930
2044         lsh r0, 32
2045         or r0, 0x100dc5c8
2046         mov32 r1, 0xdde263e
2047         lsh r1, 32
2048         or r1, 0x3cbef7f3
2049         mod r0, r1
2050         mod r0, 0x658f1778
2051         exit",
2052     )
2053     .unwrap();
2054     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
2055     assert_eq!(vm.execute_program().unwrap(), 0x30ba5a04);
2056 }
2057 
2058 #[test]
2059 fn test_vm_mov() {
2060     let prog = assemble(
2061         "
2062         mov32 r1, 1
2063         mov32 r0, r1
2064         exit",
2065     )
2066     .unwrap();
2067     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
2068     assert_eq!(vm.execute_program().unwrap(), 0x1);
2069 }
2070 
2071 #[test]
2072 fn test_vm_mul32_imm() {
2073     let prog = assemble(
2074         "
2075         mov r0, 3
2076         mul32 r0, 4
2077         exit",
2078     )
2079     .unwrap();
2080     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
2081     assert_eq!(vm.execute_program().unwrap(), 0xc);
2082 }
2083 
2084 #[test]
2085 fn test_vm_mul32_reg() {
2086     let prog = assemble(
2087         "
2088         mov r0, 3
2089         mov r1, 4
2090         mul32 r0, r1
2091         exit",
2092     )
2093     .unwrap();
2094     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
2095     assert_eq!(vm.execute_program().unwrap(), 0xc);
2096 }
2097 
2098 #[test]
2099 fn test_vm_mul32_reg_overflow() {
2100     let prog = assemble(
2101         "
2102         mov r0, 0x40000001
2103         mov r1, 4
2104         mul32 r0, r1
2105         exit",
2106     )
2107     .unwrap();
2108     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
2109     assert_eq!(vm.execute_program().unwrap(), 0x4);
2110 }
2111 
2112 #[test]
2113 fn test_vm_mul64_imm() {
2114     let prog = assemble(
2115         "
2116         mov r0, 0x40000001
2117         mul r0, 4
2118         exit",
2119     )
2120     .unwrap();
2121     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
2122     assert_eq!(vm.execute_program().unwrap(), 0x100000004);
2123 }
2124 
2125 #[test]
2126 fn test_vm_mul64_reg() {
2127     let prog = assemble(
2128         "
2129         mov r0, 0x40000001
2130         mov r1, 4
2131         mul r0, r1
2132         exit",
2133     )
2134     .unwrap();
2135     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
2136     assert_eq!(vm.execute_program().unwrap(), 0x100000004);
2137 }
2138 
2139 #[test]
2140 fn test_vm_mul_loop() {
2141     let prog = assemble(
2142         "
2143         mov r0, 0x7
2144         add r1, 0xa
2145         lsh r1, 0x20
2146         rsh r1, 0x20
2147         jeq r1, 0x0, +4
2148         mov r0, 0x7
2149         mul r0, 0x7
2150         add r1, -1
2151         jne r1, 0x0, -3
2152         exit",
2153     )
2154     .unwrap();
2155     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
2156     assert_eq!(vm.execute_program().unwrap(), 0x75db9c97);
2157 }
2158 
2159 #[test]
2160 fn test_vm_neg64() {
2161     let prog = assemble(
2162         "
2163         mov32 r0, 2
2164         neg r0
2165         exit",
2166     )
2167     .unwrap();
2168     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
2169     assert_eq!(vm.execute_program().unwrap(), 0xfffffffffffffffe);
2170 }
2171 
2172 #[test]
2173 fn test_vm_neg() {
2174     let prog = assemble(
2175         "
2176         mov32 r0, 2
2177         neg32 r0
2178         exit",
2179     )
2180     .unwrap();
2181     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
2182     assert_eq!(vm.execute_program().unwrap(), 0xfffffffe);
2183 }
2184 
2185 #[test]
2186 fn test_vm_prime() {
2187     let prog = assemble(
2188         "
2189         mov r1, 67
2190         mov r0, 0x1
2191         mov r2, 0x2
2192         jgt r1, 0x2, +4
2193         ja +10
2194         add r2, 0x1
2195         mov r0, 0x1
2196         jge r2, r1, +7
2197         mov r3, r1
2198         div r3, r2
2199         mul r3, r2
2200         mov r4, r1
2201         sub r4, r3
2202         mov r0, 0x0
2203         jne r4, 0x0, -10
2204         exit",
2205     )
2206     .unwrap();
2207     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
2208     assert_eq!(vm.execute_program().unwrap(), 0x1);
2209 }
2210 
2211 #[test]
2212 fn test_vm_rhs32() {
2213     let prog = assemble(
2214         "
2215         xor r0, r0
2216         sub r0, 1
2217         rsh32 r0, 8
2218         exit",
2219     )
2220     .unwrap();
2221     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
2222     assert_eq!(vm.execute_program().unwrap(), 0x00ffffff);
2223 }
2224 
2225 #[test]
2226 fn test_vm_rsh_reg() {
2227     let prog = assemble(
2228         "
2229         mov r0, 0x10
2230         mov r7, 4
2231         rsh r0, r7
2232         exit",
2233     )
2234     .unwrap();
2235     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
2236     assert_eq!(vm.execute_program().unwrap(), 0x1);
2237 }
2238 
2239 #[test]
2240 fn test_vm_stack() {
2241     let prog = assemble(
2242         "
2243         mov r1, 51
2244         stdw [r10-16], 0xab
2245         stdw [r10-8], 0xcd
2246         and r1, 1
2247         lsh r1, 3
2248         mov r2, r10
2249         add r2, r1
2250         ldxdw r0, [r2-16]
2251         exit",
2252     )
2253     .unwrap();
2254     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
2255     assert_eq!(vm.execute_program().unwrap(), 0xcd);
2256 }
2257 
2258 #[test]
2259 fn test_vm_stack2() {
2260     let prog = assemble(
2261         "
2262         stb [r10-4], 0x01
2263         stb [r10-3], 0x02
2264         stb [r10-2], 0x03
2265         stb [r10-1], 0x04
2266         mov r1, r10
2267         mov r2, 0x4
2268         sub r1, r2
2269         call 1
2270         mov r1, 0
2271         ldxb r2, [r10-4]
2272         ldxb r3, [r10-3]
2273         ldxb r4, [r10-2]
2274         ldxb r5, [r10-1]
2275         call 0
2276         xor r0, 0x2a2a2a2a
2277         exit",
2278     )
2279     .unwrap();
2280     let mut vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
2281     vm.register_helper(0, helpers::gather_bytes).unwrap();
2282     vm.register_helper(1, helpers::memfrob).unwrap();
2283     assert_eq!(vm.execute_program().unwrap(), 0x01020304);
2284 }
2285 
2286 #[test]
2287 fn test_vm_stb() {
2288     let prog = assemble(
2289         "
2290         stb [r1+2], 0x11
2291         ldxb r0, [r1+2]
2292         exit",
2293     )
2294     .unwrap();
2295     let mem = &mut [0xaa, 0xbb, 0xff, 0xcc, 0xdd];
2296     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
2297     assert_eq!(vm.execute_program(mem).unwrap(), 0x11);
2298 }
2299 
2300 #[test]
2301 fn test_vm_stdw() {
2302     let prog = assemble(
2303         "
2304         stdw [r1+2], 0x44332211
2305         ldxdw r0, [r1+2]
2306         exit",
2307     )
2308     .unwrap();
2309     let mem = &mut [
2310         0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd,
2311     ];
2312     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
2313     assert_eq!(vm.execute_program(mem).unwrap(), 0x44332211);
2314 }
2315 
2316 // If this case is not handled properly in check_mem(), then we may overflow when adding the
2317 // context address and the offset, and make the thread panic with "attempt to add with overflow".
2318 // Check that we panic with the expected out-of-bounds error.
2319 #[test]
2320 #[should_panic(expected = "Error: out of bounds memory store (insn #1)")]
2321 fn test_vm_stdw_add_overflow() {
2322     let prog = assemble(
2323         "
2324         stdw [r2-0x1], 0x44332211
2325         ldxw r0, [r1+2]
2326         exit",
2327     )
2328     .unwrap();
2329     let mem = &mut [
2330         0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd,
2331     ];
2332     let mut vm = rbpf::EbpfVmFixedMbuff::new(Some(&prog), 0x00, 0x10).unwrap();
2333     _ = vm.execute_program(mem).unwrap();
2334 }
2335 
2336 #[test]
2337 fn test_vm_sth() {
2338     let prog = assemble(
2339         "
2340         sth [r1+2], 0x2211
2341         ldxh r0, [r1+2]
2342         exit",
2343     )
2344     .unwrap();
2345     let mem = &mut [0xaa, 0xbb, 0xff, 0xff, 0xcc, 0xdd];
2346     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
2347     assert_eq!(vm.execute_program(mem).unwrap(), 0x2211);
2348 }
2349 
2350 #[test]
2351 fn test_vm_string_stack() {
2352     let prog = assemble(
2353         "
2354         mov r1, 0x78636261
2355         stxw [r10-8], r1
2356         mov r6, 0x0
2357         stxb [r10-4], r6
2358         stxb [r10-12], r6
2359         mov r1, 0x79636261
2360         stxw [r10-16], r1
2361         mov r1, r10
2362         add r1, -8
2363         mov r2, r1
2364         call 0x4
2365         mov r1, r0
2366         mov r0, 0x1
2367         lsh r1, 0x20
2368         rsh r1, 0x20
2369         jne r1, 0x0, +11
2370         mov r1, r10
2371         add r1, -8
2372         mov r2, r10
2373         add r2, -16
2374         call 0x4
2375         mov r1, r0
2376         lsh r1, 0x20
2377         rsh r1, 0x20
2378         mov r0, 0x1
2379         jeq r1, r6, +1
2380         mov r0, 0x0
2381         exit",
2382     )
2383     .unwrap();
2384     let mut vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
2385     vm.register_helper(4, helpers::strcmp).unwrap();
2386     assert_eq!(vm.execute_program().unwrap(), 0x0);
2387 }
2388 
2389 #[test]
2390 fn test_vm_stw() {
2391     let prog = assemble(
2392         "
2393         stw [r1+2], 0x44332211
2394         ldxw r0, [r1+2]
2395         exit",
2396     )
2397     .unwrap();
2398     let mem = &mut [0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd];
2399     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
2400     assert_eq!(vm.execute_program(mem).unwrap(), 0x44332211);
2401 }
2402 
2403 #[test]
2404 fn test_vm_stxb() {
2405     let prog = assemble(
2406         "
2407         mov32 r2, 0x11
2408         stxb [r1+2], r2
2409         ldxb r0, [r1+2]
2410         exit",
2411     )
2412     .unwrap();
2413     let mem = &mut [0xaa, 0xbb, 0xff, 0xcc, 0xdd];
2414     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
2415     assert_eq!(vm.execute_program(mem).unwrap(), 0x11);
2416 }
2417 
2418 #[test]
2419 fn test_vm_stxb_all() {
2420     let prog = assemble(
2421         "
2422         mov r0, 0xf0
2423         mov r2, 0xf2
2424         mov r3, 0xf3
2425         mov r4, 0xf4
2426         mov r5, 0xf5
2427         mov r6, 0xf6
2428         mov r7, 0xf7
2429         mov r8, 0xf8
2430         stxb [r1], r0
2431         stxb [r1+1], r2
2432         stxb [r1+2], r3
2433         stxb [r1+3], r4
2434         stxb [r1+4], r5
2435         stxb [r1+5], r6
2436         stxb [r1+6], r7
2437         stxb [r1+7], r8
2438         ldxdw r0, [r1]
2439         be64 r0
2440         exit",
2441     )
2442     .unwrap();
2443     let mem = &mut [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
2444     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
2445     assert_eq!(vm.execute_program(mem).unwrap(), 0xf0f2f3f4f5f6f7f8);
2446 }
2447 
2448 #[test]
2449 fn test_vm_stxb_all2() {
2450     let prog = assemble(
2451         "
2452         mov r0, r1
2453         mov r1, 0xf1
2454         mov r9, 0xf9
2455         stxb [r0], r1
2456         stxb [r0+1], r9
2457         ldxh r0, [r0]
2458         be16 r0
2459         exit",
2460     )
2461     .unwrap();
2462     let mem = &mut [0xff, 0xff];
2463     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
2464     assert_eq!(vm.execute_program(mem).unwrap(), 0xf1f9);
2465 }
2466 
2467 #[test]
2468 fn test_vm_stxb_chain() {
2469     let prog = assemble(
2470         "
2471         mov r0, r1
2472         ldxb r9, [r0+0]
2473         stxb [r0+1], r9
2474         ldxb r8, [r0+1]
2475         stxb [r0+2], r8
2476         ldxb r7, [r0+2]
2477         stxb [r0+3], r7
2478         ldxb r6, [r0+3]
2479         stxb [r0+4], r6
2480         ldxb r5, [r0+4]
2481         stxb [r0+5], r5
2482         ldxb r4, [r0+5]
2483         stxb [r0+6], r4
2484         ldxb r3, [r0+6]
2485         stxb [r0+7], r3
2486         ldxb r2, [r0+7]
2487         stxb [r0+8], r2
2488         ldxb r1, [r0+8]
2489         stxb [r0+9], r1
2490         ldxb r0, [r0+9]
2491         exit",
2492     )
2493     .unwrap();
2494     let mem = &mut [0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
2495     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
2496     assert_eq!(vm.execute_program(mem).unwrap(), 0x2a);
2497 }
2498 
2499 #[test]
2500 fn test_vm_stxdw() {
2501     let prog = assemble(
2502         "
2503         mov r2, -2005440939
2504         lsh r2, 32
2505         or r2, 0x44332211
2506         stxdw [r1+2], r2
2507         ldxdw r0, [r1+2]
2508         exit",
2509     )
2510     .unwrap();
2511     let mem = &mut [
2512         0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd,
2513     ];
2514     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
2515     assert_eq!(vm.execute_program(mem).unwrap(), 0x8877665544332211);
2516 }
2517 
2518 #[test]
2519 fn test_vm_stxh() {
2520     let prog = assemble(
2521         "
2522         mov32 r2, 0x2211
2523         stxh [r1+2], r2
2524         ldxh r0, [r1+2]
2525         exit",
2526     )
2527     .unwrap();
2528     let mem = &mut [0xaa, 0xbb, 0xff, 0xff, 0xcc, 0xdd];
2529     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
2530     assert_eq!(vm.execute_program(mem).unwrap(), 0x2211);
2531 }
2532 
2533 #[test]
2534 fn test_vm_stxw() {
2535     let prog = assemble(
2536         "
2537         mov32 r2, 0x44332211
2538         stxw [r1+2], r2
2539         ldxw r0, [r1+2]
2540         exit",
2541     )
2542     .unwrap();
2543     let mem = &mut [0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd];
2544     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
2545     assert_eq!(vm.execute_program(mem).unwrap(), 0x44332211);
2546 }
2547 
2548 #[test]
2549 fn test_vm_subnet() {
2550     let prog = assemble(
2551         "
2552         mov r2, 0xe
2553         ldxh r3, [r1+12]
2554         jne r3, 0x81, +2
2555         mov r2, 0x12
2556         ldxh r3, [r1+16]
2557         and r3, 0xffff
2558         jne r3, 0x8, +5
2559         add r1, r2
2560         mov r0, 0x1
2561         ldxw r1, [r1+16]
2562         and r1, 0xffffff
2563         jeq r1, 0x1a8c0, +1
2564         mov r0, 0x0
2565         exit",
2566     )
2567     .unwrap();
2568     let mem = &mut [
2569         0x00, 0x00, 0xc0, 0x9f, 0xa0, 0x97, 0x00, 0xa0, 0xcc, 0x3b, 0xbf, 0xfa, 0x08, 0x00, 0x45,
2570         0x10, 0x00, 0x3c, 0x46, 0x3c, 0x40, 0x00, 0x40, 0x06, 0x73, 0x1c, 0xc0, 0xa8, 0x01, 0x02,
2571         0xc0, 0xa8, 0x01, 0x01, 0x06, 0x0e, 0x00, 0x17, 0x99, 0xc5, 0xa0, 0xec, 0x00, 0x00, 0x00,
2572         0x00, 0xa0, 0x02, 0x7d, 0x78, 0xe0, 0xa3, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, 0x04, 0x02,
2573         0x08, 0x0a, 0x00, 0x9c, 0x27, 0x24, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x00,
2574     ];
2575     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
2576     assert_eq!(vm.execute_program(mem).unwrap(), 0x1);
2577 }
2578 
2579 const PROG_TCP_PORT_80: [u8; 152] = [
2580     0x71, 0x12, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x13, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
2581     0x67, 0x03, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2582     0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x0c, 0x00, 0x08, 0x00, 0x00, 0x00,
2583     0x71, 0x12, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x02, 0x0a, 0x00, 0x06, 0x00, 0x00, 0x00,
2584     0x71, 0x12, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x01, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
2585     0x57, 0x02, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x67, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
2586     0x0f, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
2587     0x15, 0x02, 0x02, 0x00, 0x00, 0x50, 0x00, 0x00, 0x69, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2588     0x55, 0x01, 0x01, 0x00, 0x00, 0x50, 0x00, 0x00, 0xb7, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
2589     0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2590 ];
2591 
2592 #[test]
2593 fn test_vm_tcp_port80_match() {
2594     let mem = &mut [
2595         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x08, 0x00, 0x45,
2596         0x00, 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01,
2597         0xc0, 0xa8, 0x00, 0x02, 0x27, 0x10, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2598         0x00, 0x50, 0x02, 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2599         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2600         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2601         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2602     ];
2603     let prog = &PROG_TCP_PORT_80;
2604     let vm = rbpf::EbpfVmRaw::new(Some(prog)).unwrap();
2605     assert_eq!(vm.execute_program(mem).unwrap(), 0x1);
2606 }
2607 
2608 #[test]
2609 fn test_vm_tcp_port80_nomatch() {
2610     let mem = &mut [
2611         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x08, 0x00, 0x45,
2612         0x00, 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01,
2613         0xc0, 0xa8, 0x00, 0x02, 0x00, 0x16, 0x27, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2614         0x00, 0x51, 0x02, 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2615         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2616         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2617         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2618     ];
2619     let prog = &PROG_TCP_PORT_80;
2620     let vm = rbpf::EbpfVmRaw::new(Some(prog)).unwrap();
2621     assert_eq!(vm.execute_program(mem).unwrap(), 0x0);
2622 }
2623 
2624 #[test]
2625 fn test_vm_tcp_port80_nomatch_ethertype() {
2626     let mem = &mut [
2627         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x08, 0x01, 0x45,
2628         0x00, 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01,
2629         0xc0, 0xa8, 0x00, 0x02, 0x27, 0x10, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2630         0x00, 0x50, 0x02, 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2631         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2632         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2633         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2634     ];
2635     let prog = &PROG_TCP_PORT_80;
2636     let vm = rbpf::EbpfVmRaw::new(Some(prog)).unwrap();
2637     assert_eq!(vm.execute_program(mem).unwrap(), 0x0);
2638 }
2639 
2640 #[test]
2641 fn test_vm_tcp_port80_nomatch_proto() {
2642     let mem = &mut [
2643         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x08, 0x00, 0x45,
2644         0x00, 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x11, 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01,
2645         0xc0, 0xa8, 0x00, 0x02, 0x27, 0x10, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2646         0x00, 0x50, 0x02, 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2647         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2648         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2649         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2650     ];
2651     let prog = &PROG_TCP_PORT_80;
2652     let vm = rbpf::EbpfVmRaw::new(Some(prog)).unwrap();
2653     assert_eq!(vm.execute_program(mem).unwrap(), 0x0);
2654 }
2655 
2656 #[test]
2657 fn test_vm_tcp_sack_match() {
2658     let mut mem = TCP_SACK_MATCH.to_vec();
2659     let prog = assemble(TCP_SACK_ASM).unwrap();
2660     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
2661     assert_eq!(vm.execute_program(mem.as_mut_slice()).unwrap(), 0x1);
2662 }
2663 
2664 #[test]
2665 fn test_vm_tcp_sack_nomatch() {
2666     let mut mem = TCP_SACK_NOMATCH.to_vec();
2667     let prog = assemble(TCP_SACK_ASM).unwrap();
2668     let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
2669     assert_eq!(vm.execute_program(mem.as_mut_slice()).unwrap(), 0x0);
2670 }
2671