Add eBPF instruction CALLX for indirect calls #7972
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Hello,
When clang encounters indirect calls in eBPF programs, it emits a call instruction with a register parameter (
BPF_X
) instead of an immediate value (BPF_K
). This encoding (BPF_JMP | BPF_CALL | BPF_X = 0x8d
) is decoded by llvm-objdump ascallx
.For example, here is a simple C program with an indirect call:
Compiling and disassembling it gives with clang 14.0 (and LLVM 14.0):
Contrary to usual eBPF instructions,
callx
's register operand is encoded in the immediate field. This encoding is actually specific to LLVM (and clang). GCC used the destination register to store the target register.LLVM 19.1 was modified to use GCC's encoding: llvm/llvm-project#81546 ("BPF: Change callx insn encoding"). For example, in an Alpine Linux 3.21 system:
The instruction is now encoded
8d 01 00...
.For reference, here are similar commands using GCC showing it is using the same encoding (here, compiler option
-mxbpf
is required to enable several features including indirect calls, cf. https://gcc.gnu.org/onlinedocs/gcc-12.4.0/gcc/eBPF-Options.html).Add both
callx
instruction encodings to eBPF processor.By the way, the eBPF Verifier used by Linux kernel currently forbids indirect calls (it fails when
BPF_SRC(insn->code) != BPF_K
, in https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/bpf/verifier.c?h=v6.14#n19141). But other deployments of eBPF may already support this feature.