|
@@ -289,23 +289,41 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
|
|
case BPF_ALU | BPF_END | BPF_FROM_BE:
|
|
|
#ifdef CONFIG_CPU_BIG_ENDIAN
|
|
|
if (BPF_SRC(code) == BPF_FROM_BE)
|
|
|
- break;
|
|
|
+ goto emit_bswap_uxt;
|
|
|
#else /* !CONFIG_CPU_BIG_ENDIAN */
|
|
|
if (BPF_SRC(code) == BPF_FROM_LE)
|
|
|
- break;
|
|
|
+ goto emit_bswap_uxt;
|
|
|
#endif
|
|
|
switch (imm) {
|
|
|
case 16:
|
|
|
emit(A64_REV16(is64, dst, dst), ctx);
|
|
|
+ /* zero-extend 16 bits into 64 bits */
|
|
|
+ emit(A64_UXTH(is64, dst, dst), ctx);
|
|
|
break;
|
|
|
case 32:
|
|
|
emit(A64_REV32(is64, dst, dst), ctx);
|
|
|
+ /* upper 32 bits already cleared */
|
|
|
break;
|
|
|
case 64:
|
|
|
emit(A64_REV64(dst, dst), ctx);
|
|
|
break;
|
|
|
}
|
|
|
break;
|
|
|
+emit_bswap_uxt:
|
|
|
+ switch (imm) {
|
|
|
+ case 16:
|
|
|
+ /* zero-extend 16 bits into 64 bits */
|
|
|
+ emit(A64_UXTH(is64, dst, dst), ctx);
|
|
|
+ break;
|
|
|
+ case 32:
|
|
|
+ /* zero-extend 32 bits into 64 bits */
|
|
|
+ emit(A64_UXTW(is64, dst, dst), ctx);
|
|
|
+ break;
|
|
|
+ case 64:
|
|
|
+ /* nop */
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ break;
|
|
|
/* dst = imm */
|
|
|
case BPF_ALU | BPF_MOV | BPF_K:
|
|
|
case BPF_ALU64 | BPF_MOV | BPF_K:
|