@@ -975,29 +975,42 @@ static inline void emit_a32_mul_r64(const s8 dst[], const s8 src[],
975
975
}
976
976
977
977
/* *(size *)(dst + off) = src */
978
- static inline void emit_str_r (const s8 dst , const s8 src ,
979
- const s32 off , struct jit_ctx * ctx , const u8 sz ){
978
+ static inline void emit_str_r (const s8 dst , const s8 src [] ,
979
+ s32 off , struct jit_ctx * ctx , const u8 sz ){
980
980
const s8 * tmp = bpf2a32 [TMP_REG_1 ];
981
+ s32 off_max ;
981
982
s8 rd ;
982
983
983
984
rd = arm_bpf_get_reg32 (dst , tmp [1 ], ctx );
984
- if (off ) {
985
+
986
+ if (sz == BPF_H )
987
+ off_max = 0xff ;
988
+ else
989
+ off_max = 0xfff ;
990
+
991
+ if (off < 0 || off > off_max ) {
985
992
emit_a32_mov_i (tmp [0 ], off , ctx );
986
- emit (ARM_ADD_R (tmp [0 ], rd , tmp [0 ]), ctx );
993
+ emit (ARM_ADD_R (tmp [0 ], tmp [0 ], rd ), ctx );
987
994
rd = tmp [0 ];
995
+ off = 0 ;
988
996
}
989
997
switch (sz ) {
990
- case BPF_W :
991
- /* Store a Word */
992
- emit (ARM_STR_I ( src , rd , 0 ), ctx );
998
+ case BPF_B :
999
+ /* Store a Byte */
1000
+ emit (ARM_STRB_I ( src_lo , rd , off ), ctx );
993
1001
break ;
994
1002
case BPF_H :
995
1003
/* Store a HalfWord */
996
- emit (ARM_STRH_I (src , rd , 0 ), ctx );
1004
+ emit (ARM_STRH_I (src_lo , rd , off ), ctx );
997
1005
break ;
998
- case BPF_B :
999
- /* Store a Byte */
1000
- emit (ARM_STRB_I (src , rd , 0 ), ctx );
1006
+ case BPF_W :
1007
+ /* Store a Word */
1008
+ emit (ARM_STR_I (src_lo , rd , off ), ctx );
1009
+ break ;
1010
+ case BPF_DW :
1011
+ /* Store a Double Word */
1012
+ emit (ARM_STR_I (src_lo , rd , off ), ctx );
1013
+ emit (ARM_STR_I (src_hi , rd , off + 4 ), ctx );
1001
1014
break ;
1002
1015
}
1003
1016
}
@@ -1539,16 +1552,14 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
1539
1552
case BPF_DW :
1540
1553
/* Sign-extend immediate value into temp reg */
1541
1554
emit_a32_mov_se_i64 (true, tmp2 , imm , ctx );
1542
- emit_str_r (dst_lo , tmp2 [1 ], off , ctx , BPF_W );
1543
- emit_str_r (dst_lo , tmp2 [0 ], off + 4 , ctx , BPF_W );
1544
1555
break ;
1545
1556
case BPF_W :
1546
1557
case BPF_H :
1547
1558
case BPF_B :
1548
1559
emit_a32_mov_i (tmp2 [1 ], imm , ctx );
1549
- emit_str_r (dst_lo , tmp2 [1 ], off , ctx , BPF_SIZE (code ));
1550
1560
break ;
1551
1561
}
1562
+ emit_str_r (dst_lo , tmp2 , off , ctx , BPF_SIZE (code ));
1552
1563
break ;
1553
1564
/* STX XADD: lock *(u32 *)(dst + off) += src */
1554
1565
case BPF_STX | BPF_XADD | BPF_W :
@@ -1560,20 +1571,9 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
1560
1571
case BPF_STX | BPF_MEM | BPF_H :
1561
1572
case BPF_STX | BPF_MEM | BPF_B :
1562
1573
case BPF_STX | BPF_MEM | BPF_DW :
1563
- {
1564
- u8 sz = BPF_SIZE (code );
1565
-
1566
1574
rs = arm_bpf_get_reg64 (src , tmp2 , ctx );
1567
-
1568
- /* Store the value */
1569
- if (BPF_SIZE (code ) == BPF_DW ) {
1570
- emit_str_r (dst_lo , rs [1 ], off , ctx , BPF_W );
1571
- emit_str_r (dst_lo , rs [0 ], off + 4 , ctx , BPF_W );
1572
- } else {
1573
- emit_str_r (dst_lo , rs [1 ], off , ctx , sz );
1574
- }
1575
+ emit_str_r (dst_lo , rs , off , ctx , BPF_SIZE (code ));
1575
1576
break ;
1576
- }
1577
1577
/* PC += off if dst == src */
1578
1578
/* PC += off if dst > src */
1579
1579
/* PC += off if dst >= src */
0 commit comments