|
@@ -975,29 +975,42 @@ static inline void emit_a32_mul_r64(const s8 dst[], const s8 src[],
|
|
}
|
|
}
|
|
|
|
|
|
/* *(size *)(dst + off) = src */
|
|
/* *(size *)(dst + off) = src */
|
|
-static inline void emit_str_r(const s8 dst, const s8 src,
|
|
|
|
- const s32 off, struct jit_ctx *ctx, const u8 sz){
|
|
|
|
|
|
+static inline void emit_str_r(const s8 dst, const s8 src[],
|
|
|
|
+ s32 off, struct jit_ctx *ctx, const u8 sz){
|
|
const s8 *tmp = bpf2a32[TMP_REG_1];
|
|
const s8 *tmp = bpf2a32[TMP_REG_1];
|
|
|
|
+ s32 off_max;
|
|
s8 rd;
|
|
s8 rd;
|
|
|
|
|
|
rd = arm_bpf_get_reg32(dst, tmp[1], ctx);
|
|
rd = arm_bpf_get_reg32(dst, tmp[1], ctx);
|
|
- if (off) {
|
|
|
|
|
|
+
|
|
|
|
+ if (sz == BPF_H)
|
|
|
|
+ off_max = 0xff;
|
|
|
|
+ else
|
|
|
|
+ off_max = 0xfff;
|
|
|
|
+
|
|
|
|
+ if (off < 0 || off > off_max) {
|
|
emit_a32_mov_i(tmp[0], off, ctx);
|
|
emit_a32_mov_i(tmp[0], off, ctx);
|
|
- emit(ARM_ADD_R(tmp[0], rd, tmp[0]), ctx);
|
|
|
|
|
|
+ emit(ARM_ADD_R(tmp[0], tmp[0], rd), ctx);
|
|
rd = tmp[0];
|
|
rd = tmp[0];
|
|
|
|
+ off = 0;
|
|
}
|
|
}
|
|
switch (sz) {
|
|
switch (sz) {
|
|
- case BPF_W:
|
|
|
|
- /* Store a Word */
|
|
|
|
- emit(ARM_STR_I(src, rd, 0), ctx);
|
|
|
|
|
|
+ case BPF_B:
|
|
|
|
+ /* Store a Byte */
|
|
|
|
+ emit(ARM_STRB_I(src_lo, rd, off), ctx);
|
|
break;
|
|
break;
|
|
case BPF_H:
|
|
case BPF_H:
|
|
/* Store a HalfWord */
|
|
/* Store a HalfWord */
|
|
- emit(ARM_STRH_I(src, rd, 0), ctx);
|
|
|
|
|
|
+ emit(ARM_STRH_I(src_lo, rd, off), ctx);
|
|
break;
|
|
break;
|
|
- case BPF_B:
|
|
|
|
- /* Store a Byte */
|
|
|
|
- emit(ARM_STRB_I(src, rd, 0), ctx);
|
|
|
|
|
|
+ case BPF_W:
|
|
|
|
+ /* Store a Word */
|
|
|
|
+ emit(ARM_STR_I(src_lo, rd, off), ctx);
|
|
|
|
+ break;
|
|
|
|
+ case BPF_DW:
|
|
|
|
+ /* Store a Double Word */
|
|
|
|
+ emit(ARM_STR_I(src_lo, rd, off), ctx);
|
|
|
|
+ emit(ARM_STR_I(src_hi, rd, off + 4), ctx);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1539,16 +1552,14 @@ exit:
|
|
case BPF_DW:
|
|
case BPF_DW:
|
|
/* Sign-extend immediate value into temp reg */
|
|
/* Sign-extend immediate value into temp reg */
|
|
emit_a32_mov_se_i64(true, tmp2, imm, ctx);
|
|
emit_a32_mov_se_i64(true, tmp2, imm, ctx);
|
|
- emit_str_r(dst_lo, tmp2[1], off, ctx, BPF_W);
|
|
|
|
- emit_str_r(dst_lo, tmp2[0], off+4, ctx, BPF_W);
|
|
|
|
break;
|
|
break;
|
|
case BPF_W:
|
|
case BPF_W:
|
|
case BPF_H:
|
|
case BPF_H:
|
|
case BPF_B:
|
|
case BPF_B:
|
|
emit_a32_mov_i(tmp2[1], imm, ctx);
|
|
emit_a32_mov_i(tmp2[1], imm, ctx);
|
|
- emit_str_r(dst_lo, tmp2[1], off, ctx, BPF_SIZE(code));
|
|
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
+ emit_str_r(dst_lo, tmp2, off, ctx, BPF_SIZE(code));
|
|
break;
|
|
break;
|
|
/* STX XADD: lock *(u32 *)(dst + off) += src */
|
|
/* STX XADD: lock *(u32 *)(dst + off) += src */
|
|
case BPF_STX | BPF_XADD | BPF_W:
|
|
case BPF_STX | BPF_XADD | BPF_W:
|
|
@@ -1560,20 +1571,9 @@ exit:
|
|
case BPF_STX | BPF_MEM | BPF_H:
|
|
case BPF_STX | BPF_MEM | BPF_H:
|
|
case BPF_STX | BPF_MEM | BPF_B:
|
|
case BPF_STX | BPF_MEM | BPF_B:
|
|
case BPF_STX | BPF_MEM | BPF_DW:
|
|
case BPF_STX | BPF_MEM | BPF_DW:
|
|
- {
|
|
|
|
- u8 sz = BPF_SIZE(code);
|
|
|
|
-
|
|
|
|
rs = arm_bpf_get_reg64(src, tmp2, ctx);
|
|
rs = arm_bpf_get_reg64(src, tmp2, ctx);
|
|
-
|
|
|
|
- /* Store the value */
|
|
|
|
- if (BPF_SIZE(code) == BPF_DW) {
|
|
|
|
- emit_str_r(dst_lo, rs[1], off, ctx, BPF_W);
|
|
|
|
- emit_str_r(dst_lo, rs[0], off+4, ctx, BPF_W);
|
|
|
|
- } else {
|
|
|
|
- emit_str_r(dst_lo, rs[1], off, ctx, sz);
|
|
|
|
- }
|
|
|
|
|
|
+ emit_str_r(dst_lo, rs, off, ctx, BPF_SIZE(code));
|
|
break;
|
|
break;
|
|
- }
|
|
|
|
/* PC += off if dst == src */
|
|
/* PC += off if dst == src */
|
|
/* PC += off if dst > src */
|
|
/* PC += off if dst > src */
|
|
/* PC += off if dst >= src */
|
|
/* PC += off if dst >= src */
|