@@ -877,6 +877,65 @@ fn test_jit_mod_by_zero_reg() {
877877 }
878878}
879879
880+ #[ test]
881+ fn test_jit_div_reg_with_nonzero_imm ( ) {
882+ // This test checks the fix for using is_reg instead of imm != 0
883+ // when deciding whether to load an immediate or move a register for the divisor.
884+ // Hand-crafted bytecode with DIV (register mode) but non-zero immediate field.
885+ // The immediate should be ignored for register operations.
886+ #[ rustfmt:: skip]
887+ let prog = & [
888+ // mov r0, 100
889+ 0xb7 , 0x00 , 0x00 , 0x00 , 0x64 , 0x00 , 0x00 , 0x00 ,
890+ // mov r1, 5
891+ 0xb7 , 0x01 , 0x00 , 0x00 , 0x05 , 0x00 , 0x00 , 0x00 ,
892+ // div r0, r1 (but with non-zero immediate field 0x99999999)
893+ // Opcode 0x3f = DIV64 | BPF_X (register mode)
894+ 0x3f , 0x10 , 0x00 , 0x00 , 0x99 , 0x99 , 0x99 , 0x99 ,
895+ // exit
896+ 0x95 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
897+ ] ;
898+
899+ let mut vm = rbpf:: EbpfVmNoData :: new ( Some ( prog) ) . unwrap ( ) ;
900+ #[ cfg( not( feature = "std" ) ) ]
901+ let mut exec_mem = alloc_exec_memory ( ) ;
902+ #[ cfg( not( feature = "std" ) ) ]
903+ vm. set_jit_exec_memory ( & mut exec_mem) . unwrap ( ) ;
904+ vm. jit_compile ( ) . unwrap ( ) ;
905+ unsafe {
906+ // Should divide 100 by r1 (5), not by the immediate (0x99999999)
907+ assert_eq ! ( vm. execute_program_jit( ) . unwrap( ) , 0x14 ) ; // 100 / 5 = 20 (0x14)
908+ }
909+ }
910+
911+ #[ test]
912+ fn test_jit_mod_reg_with_nonzero_imm ( ) {
913+ // Companion test for modulo operation with non-zero immediate in register mode
914+ #[ rustfmt:: skip]
915+ let prog = & [
916+ // mov r0, 107
917+ 0xb7 , 0x00 , 0x00 , 0x00 , 0x6b , 0x00 , 0x00 , 0x00 ,
918+ // mov r1, 5
919+ 0xb7 , 0x01 , 0x00 , 0x00 , 0x05 , 0x00 , 0x00 , 0x00 ,
920+ // mod r0, r1 (but with non-zero immediate field 0x88888888)
921+ // Opcode 0x9f = MOD64 | BPF_X (register mode)
922+ 0x9f , 0x10 , 0x00 , 0x00 , 0x88 , 0x88 , 0x88 , 0x88 ,
923+ // exit
924+ 0x95 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
925+ ] ;
926+
927+ let mut vm = rbpf:: EbpfVmNoData :: new ( Some ( prog) ) . unwrap ( ) ;
928+ #[ cfg( not( feature = "std" ) ) ]
929+ let mut exec_mem = alloc_exec_memory ( ) ;
930+ #[ cfg( not( feature = "std" ) ) ]
931+ vm. set_jit_exec_memory ( & mut exec_mem) . unwrap ( ) ;
932+ vm. jit_compile ( ) . unwrap ( ) ;
933+ unsafe {
934+ // Should modulo 107 by r1 (5), not by the immediate (0x88888888)
935+ assert_eq ! ( vm. execute_program_jit( ) . unwrap( ) , 0x2 ) ; // 107 % 5 = 2
936+ }
937+ }
938+
880939// TODO SKIP: JIT disabled for this testcase (stack oob check not implemented)
881940// #[test]
882941// #[should_panic(expected = "Error: out of bounds memory store (insn #1)")]
0 commit comments