|
@@ -1452,83 +1452,6 @@ exit:
|
|
|
emit(ARM_LDR_I(rn, ARM_SP, STACK_VAR(src_lo)), ctx);
|
|
|
emit_ldx_r(dst, rn, dstk, off, ctx, BPF_SIZE(code));
|
|
|
break;
|
|
|
- /* R0 = ntohx(*(size *)(((struct sk_buff *)R6)->data + imm)) */
|
|
|
- case BPF_LD | BPF_ABS | BPF_W:
|
|
|
- case BPF_LD | BPF_ABS | BPF_H:
|
|
|
- case BPF_LD | BPF_ABS | BPF_B:
|
|
|
- /* R0 = ntohx(*(size *)(((struct sk_buff *)R6)->data + src + imm)) */
|
|
|
- case BPF_LD | BPF_IND | BPF_W:
|
|
|
- case BPF_LD | BPF_IND | BPF_H:
|
|
|
- case BPF_LD | BPF_IND | BPF_B:
|
|
|
- {
|
|
|
- const u8 r4 = bpf2a32[BPF_REG_6][1]; /* r4 = ptr to sk_buff */
|
|
|
- const u8 r0 = bpf2a32[BPF_REG_0][1]; /*r0: struct sk_buff *skb*/
|
|
|
- /* rtn value */
|
|
|
- const u8 r1 = bpf2a32[BPF_REG_0][0]; /* r1: int k */
|
|
|
- const u8 r2 = bpf2a32[BPF_REG_1][1]; /* r2: unsigned int size */
|
|
|
- const u8 r3 = bpf2a32[BPF_REG_1][0]; /* r3: void *buffer */
|
|
|
- const u8 r6 = bpf2a32[TMP_REG_1][1]; /* r6: void *(*func)(..) */
|
|
|
- int size;
|
|
|
-
|
|
|
- /* Setting up first argument */
|
|
|
- emit(ARM_MOV_R(r0, r4), ctx);
|
|
|
-
|
|
|
- /* Setting up second argument */
|
|
|
- emit_a32_mov_i(r1, imm, false, ctx);
|
|
|
- if (BPF_MODE(code) == BPF_IND)
|
|
|
- emit_a32_alu_r(r1, src_lo, false, sstk, ctx,
|
|
|
- false, false, BPF_ADD);
|
|
|
-
|
|
|
- /* Setting up third argument */
|
|
|
- switch (BPF_SIZE(code)) {
|
|
|
- case BPF_W:
|
|
|
- size = 4;
|
|
|
- break;
|
|
|
- case BPF_H:
|
|
|
- size = 2;
|
|
|
- break;
|
|
|
- case BPF_B:
|
|
|
- size = 1;
|
|
|
- break;
|
|
|
- default:
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- emit_a32_mov_i(r2, size, false, ctx);
|
|
|
-
|
|
|
- /* Setting up fourth argument */
|
|
|
- emit(ARM_ADD_I(r3, ARM_SP, imm8m(SKB_BUFFER)), ctx);
|
|
|
-
|
|
|
- /* Setting up function pointer to call */
|
|
|
- emit_a32_mov_i(r6, (unsigned int)bpf_load_pointer, false, ctx);
|
|
|
- emit_blx_r(r6, ctx);
|
|
|
-
|
|
|
- emit(ARM_EOR_R(r1, r1, r1), ctx);
|
|
|
- /* Check if return address is NULL or not.
|
|
|
- * if NULL then jump to epilogue
|
|
|
- * else continue to load the value from retn address
|
|
|
- */
|
|
|
- emit(ARM_CMP_I(r0, 0), ctx);
|
|
|
- jmp_offset = epilogue_offset(ctx);
|
|
|
- check_imm24(jmp_offset);
|
|
|
- _emit(ARM_COND_EQ, ARM_B(jmp_offset), ctx);
|
|
|
-
|
|
|
- /* Load value from the address */
|
|
|
- switch (BPF_SIZE(code)) {
|
|
|
- case BPF_W:
|
|
|
- emit(ARM_LDR_I(r0, r0, 0), ctx);
|
|
|
- emit_rev32(r0, r0, ctx);
|
|
|
- break;
|
|
|
- case BPF_H:
|
|
|
- emit(ARM_LDRH_I(r0, r0, 0), ctx);
|
|
|
- emit_rev16(r0, r0, ctx);
|
|
|
- break;
|
|
|
- case BPF_B:
|
|
|
- emit(ARM_LDRB_I(r0, r0, 0), ctx);
|
|
|
- /* No need to reverse */
|
|
|
- break;
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
/* ST: *(size *)(dst + off) = imm */
|
|
|
case BPF_ST | BPF_MEM | BPF_W:
|
|
|
case BPF_ST | BPF_MEM | BPF_H:
|