@@ -913,33 +913,53 @@ static inline void emit_str_r(const u8 dst, const u8 src, bool dstk,
913913}
914914
915915/* dst = *(size*)(src + off) */
916- static inline void emit_ldx_r (const u8 dst , const u8 src , bool dstk ,
917- const s32 off , struct jit_ctx * ctx , const u8 sz ){
916+ static inline void emit_ldx_r (const u8 dst [] , const u8 src , bool dstk ,
917+ s32 off , struct jit_ctx * ctx , const u8 sz ){
918918 const u8 * tmp = bpf2a32 [TMP_REG_1 ];
919- u8 rd = dstk ? tmp [ 1 ] : dst ;
919+ const u8 * rd = dstk ? tmp : dst ;
920920 u8 rm = src ;
921+ s32 off_max ;
921922
922- if (off ) {
923+ if (sz == BPF_H )
924+ off_max = 0xff ;
925+ else
926+ off_max = 0xfff ;
927+
928+ if (off < 0 || off > off_max ) {
923929 emit_a32_mov_i (tmp [0 ], off , false, ctx );
924930 emit (ARM_ADD_R (tmp [0 ], tmp [0 ], src ), ctx );
925931 rm = tmp [0 ];
932+ off = 0 ;
933+ } else if (rd [1 ] == rm ) {
934+ emit (ARM_MOV_R (tmp [0 ], rm ), ctx );
935+ rm = tmp [0 ];
926936 }
927937 switch (sz ) {
928- case BPF_W :
929- /* Load a Word */
930- emit (ARM_LDR_I (rd , rm , 0 ), ctx );
938+ case BPF_B :
939+ /* Load a Byte */
940+ emit (ARM_LDRB_I (rd [1 ], rm , off ), ctx );
941+ emit_a32_mov_i (dst [0 ], 0 , dstk , ctx );
931942 break ;
932943 case BPF_H :
933944 /* Load a HalfWord */
934- emit (ARM_LDRH_I (rd , rm , 0 ), ctx );
945+ emit (ARM_LDRH_I (rd [1 ], rm , off ), ctx );
946+ emit_a32_mov_i (dst [0 ], 0 , dstk , ctx );
935947 break ;
936- case BPF_B :
937- /* Load a Byte */
938- emit (ARM_LDRB_I (rd , rm , 0 ), ctx );
948+ case BPF_W :
949+ /* Load a Word */
950+ emit (ARM_LDR_I (rd [1 ], rm , off ), ctx );
951+ emit_a32_mov_i (dst [0 ], 0 , dstk , ctx );
952+ break ;
953+ case BPF_DW :
954+ /* Load a Double Word */
955+ emit (ARM_LDR_I (rd [1 ], rm , off ), ctx );
956+ emit (ARM_LDR_I (rd [0 ], rm , off + 4 ), ctx );
939957 break ;
940958 }
941959 if (dstk )
942- emit (ARM_STR_I (rd , ARM_SP , STACK_VAR (dst )), ctx );
960+ emit (ARM_STR_I (rd [1 ], ARM_SP , STACK_VAR (dst [1 ])), ctx );
961+ if (dstk && sz == BPF_DW )
962+ emit (ARM_STR_I (rd [0 ], ARM_SP , STACK_VAR (dst [0 ])), ctx );
943963}
944964
945965/* Arithmatic Operation */
@@ -1440,22 +1460,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
14401460 rn = sstk ? tmp2 [1 ] : src_lo ;
14411461 if (sstk )
14421462 emit (ARM_LDR_I (rn , ARM_SP , STACK_VAR (src_lo )), ctx );
1443- switch (BPF_SIZE (code )) {
1444- case BPF_W :
1445- /* Load a Word */
1446- case BPF_H :
1447- /* Load a Half-Word */
1448- case BPF_B :
1449- /* Load a Byte */
1450- emit_ldx_r (dst_lo , rn , dstk , off , ctx , BPF_SIZE (code ));
1451- emit_a32_mov_i (dst_hi , 0 , dstk , ctx );
1452- break ;
1453- case BPF_DW :
1454- /* Load a double word */
1455- emit_ldx_r (dst_lo , rn , dstk , off , ctx , BPF_W );
1456- emit_ldx_r (dst_hi , rn , dstk , off + 4 , ctx , BPF_W );
1457- break ;
1458- }
1463+ emit_ldx_r (dst , rn , dstk , off , ctx , BPF_SIZE (code ));
14591464 break ;
14601465 /* R0 = ntohx(*(size *)(((struct sk_buff *)R6)->data + imm)) */
14611466 case BPF_LD | BPF_ABS | BPF_W :
0 commit comments