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]
test_vm_add()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]
test_vm_alu64_arith()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]
test_vm_alu64_bit()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]
test_vm_alu_arith()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]
test_vm_alu_bit()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]
test_vm_arsh32_high_shift()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]
test_vm_arsh()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]
test_vm_arsh64()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]
test_vm_arsh_reg()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]
test_vm_arsh_imm_overflow()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]
test_vm_arsh_reg_overflow()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]
test_vm_arsh32_imm_overflow()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]
test_vm_arsh32_reg_overflow()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]
test_vm_be16()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]
test_vm_be16_high()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]
test_vm_be32()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]
test_vm_be32_high()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]
test_vm_be64()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]
test_vm_call()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]
test_vm_call_memfrob()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]
test_vm_div32_high_divisor()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]
test_vm_div32_imm()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]
test_vm_div32_reg()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]
test_vm_div64_imm()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]
test_vm_div64_reg()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]
test_vm_early_exit()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)")]
test_vm_err_call_unreg()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]
test_vm_div64_by_zero_imm()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]
test_vm_div_by_zero_imm()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]
test_vm_mod64_by_zero_imm()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]
test_vm_mod_by_zero_imm()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]
test_vm_mod_by_zero_reg_long()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]
test_vm_div64_by_zero_reg()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]
test_vm_div_by_zero_reg()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]
test_vm_div_by_zero_reg_long()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]
test_vm_mod64_by_zero_reg()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]
test_vm_mod_by_zero_reg()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)")]
test_vm_err_stack_out_of_bound()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]
test_vm_exit()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]
test_vm_ja()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]
test_vm_jeq_imm()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]
test_vm_jeq_reg()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]
test_vm_jge_imm()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]
test_vm_jle_imm()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]
test_vm_jle_reg()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]
test_vm_jgt_imm()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]
test_vm_jgt_reg()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]
test_vm_jlt_imm()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]
test_vm_jlt_reg()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]
test_vm_jit_bounce()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]
test_vm_jne_reg()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]
test_vm_jset_imm()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]
test_vm_jset_reg()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]
test_vm_jsge_imm()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]
test_vm_jsge_reg()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]
test_vm_jsle_imm()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]
test_vm_jsle_reg()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]
test_vm_jsgt_imm()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]
test_vm_jsgt_reg()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]
test_vm_jslt_imm()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]
test_vm_jslt_reg()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]
test_vm_jeq32_imm()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]
test_vm_jeq32_reg()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]
test_vm_jge32_imm()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]
test_vm_jge32_reg()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]
test_vm_jgt32_imm()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]
test_vm_jgt32_reg()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]
test_vm_jle32_imm()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]
test_vm_jle32_reg()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]
test_vm_jlt32_imm()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]
test_vm_jlt32_reg()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]
test_vm_jne32_imm()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]
test_vm_jne32_reg()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]
test_vm_jset32_imm()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]
test_vm_jset32_reg()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]
test_vm_jsge32_imm()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]
test_vm_jsge32_reg()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]
test_vm_jsgt32_imm()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]
test_vm_jsgt32_reg()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]
test_vm_jsle32_imm()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]
test_vm_jsle32_reg()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]
test_vm_jslt32_imm()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]
test_vm_jslt32_reg()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]
test_vm_lddw()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]
test_vm_lddw2()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]
test_vm_ldxb_all()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]
test_vm_ldxb()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]
test_vm_ldxdw()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]
test_vm_ldxh_all()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]
test_vm_ldxh_all2()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]
test_vm_ldxh()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]
test_vm_ldxh_same_reg()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]
test_vm_ldxw_all()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]
test_vm_ldxw()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]
test_vm_le16()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]
test_vm_le32()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]
test_vm_le64()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]
test_vm_lsh_imm()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]
test_vm_lsh_reg()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]
test_vm_lsh32_imm()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]
test_vm_lsh32_reg()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]
test_vm_lsh_imm_overflow()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]
test_vm_lsh_reg_overflow()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]
test_vm_lsh32_imm_overflow()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]
test_vm_lsh32_reg_overflow()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]
test_vm_mod()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]
test_vm_mod32()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]
test_vm_mod64()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]
test_vm_mov()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]
test_vm_mul32_imm()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]
test_vm_mul32_reg()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]
test_vm_mul32_reg_overflow()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]
test_vm_mul64_imm()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]
test_vm_mul64_reg()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]
test_vm_mul_loop()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]
test_vm_neg64()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]
test_vm_neg()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]
test_vm_prime()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]
test_vm_rhs32()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]
test_vm_rsh_reg()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]
test_vm_stack()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]
test_vm_stack2()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]
test_vm_stb()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]
test_vm_stdw()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)")]
test_vm_stdw_add_overflow()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]
test_vm_sth()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]
test_vm_string_stack()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]
test_vm_stw()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]
test_vm_stxb()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]
test_vm_stxb_all()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]
test_vm_stxb_all2()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]
test_vm_stxb_chain()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]
test_vm_stxdw()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]
test_vm_stxh()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]
test_vm_stxw()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]
test_vm_subnet()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]
test_vm_tcp_port80_match()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]
test_vm_tcp_port80_nomatch()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]
test_vm_tcp_port80_nomatch_ethertype()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]
test_vm_tcp_port80_nomatch_proto()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]
test_vm_tcp_sack_match()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]
test_vm_tcp_sack_nomatch()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