Repository navigation
BPF: Allow all libcalls - #165353
BPF: Allow all libcalls#165353vadorovsky wants to merge 1 commit into
Conversation
This comment has been minimized.
This comment has been minimized.
a3aa819 to
eb1245c
Compare
This comment has been minimized.
This comment has been minimized.
eb1245c to
1eddb5e
Compare
This comment has been minimized.
This comment has been minimized.
|
This will need some sort of gating on llvm23. Your best bet to find how to do that is to look at earlier LLVM upgrades/old version removals which will be removing code conditional on llvm version. |
1eddb5e to
f698433
Compare
Good point. To avoid slapping |
f698433 to
23240bd
Compare
| } | ||
|
|
||
| if get_version() < (24, 0, 0) && wants_wasm_eh(&sess.target) { | ||
| if llvm_major < 24 && wants_wasm_eh(&sess.target) { |
There was a problem hiding this comment.
Happy to switch WASM over to llvm_args_by_version in a follow-up change.
This comment has been minimized.
This comment has been minimized.
By default, BPF backend in LLVM allows only `memcpy`, `memset` and `memmove` libcalls. However, `core/src/ops/arith.rs:932` emits an `__extendhfsf2` libcall. LLVM 23 provides an opt-in mode that lets BPF runtimes supply implementations for otherwise unsupported libcalls.[0] Enable it unconditionally instead of enforcing LLVM's fixed allowlist. This defers validation of libcalls (and rejection of undefined ones) to BPF program consumers such as loaders and VMs. libbpf rejects ordinary undefined functions without BTF metadata.[1] Aya generally rejects unresolved calls during relocation.[2] If LLVM's unresolved `call -1` placeholder reaches the Linux verifier unchanged,[3] its relative target is the call itself, so the verifier rejects it as recursion.[4] SBPF's ELF loader rejects external symbols absent from the loader's function registry when `reject_broken_elfs` option is enabled.[5] Agave enables it while deploying and upgrading programs.[6] Users can therefore satisfy a libcall through a linked implementation or a runtime-provided function, while genuinely unresolved calls still fail during loading, verification or execution. Runtimes can also add libcalls without coordinating an allowlist change with LLVM. Given that the opt-in flag for libcalls is available only in specific LLVM versions (>=23), add `llvm_args_by_version` field to `TargetOptions`, that allows to specify LLVM arguments by version. Code in this change is generated by (an open-weight and self-hosted) LLM, it was agreed on in the Zulip thread [7], where @nagisa volunteered as a reviewer. [0] llvm/llvm-project@8446b9ffb [1] llvm/llvm-project#199542 [2] https://github.com/libbpf/libbpf/blob/f7081a/src/libbpf.c#L4345-L4350 [3] https://github.com/aya-rs/aya/blob/15a0de/aya-obj/src/relocation.rs#L606-L614 [4] https://github.com/torvalds/linux/blob/f5bbbfec5/kernel/bpf/verifier.c#L2798-L2800 [5] https://github.com/torvalds/linux/blob/f5bbbfec5/kernel/bpf/verifier.c#L2952-L2958 [6] https://github.com/anza-xyz/sbpf/blob/45bbcb/src/elf.rs#L1223-L1227 [7] https://rust-lang.zulipchat.com/#narrow/channel/606558-llm-reviews/topic/Seeking.20review.20for.20BPF.20bytecode.20linking.20.28issue.20.23135175.29/near/631892496
23240bd to
ec59c78
Compare
|
☔ The latest upstream changes (presumably #165777) made this pull request unmergeable. Please resolve the merge conflicts by rebasing. |
By default, BPF backend in LLVM allows only
memcpy,memsetandmemmovelibcalls.However,
core/src/opts/arith.rs:932emits an__extendhfsf2libcall.LLVM 23 provides an opt-in mode that lets BPF runtimes supply implementations for otherwise unsupported libcalls.[0] Enable it unconditionally instead of enforcing LLVM's fixed allowlist.
This defers validation of libcalls (and rejection of undefined ones) to BPF program consumers such as loaders and VMs. libbpf rejects ordinary undefined functions without BTF metadata.[1] Aya generally rejects unresolved calls during relocation.[2] If LLVM's unresolved
call -1placeholder reaches the Linux verifier unchanged,[3] its relative target is the call itself, so the verifier rejects it as recursion.[4] SBPF's ELF loader rejects external symbols absent from the loader's function registry whenreject_broken_elfsoption is enabled.[5] Agave enables it while deploying and upgrading programs.[6]Users can therefore satisfy a libcall through a linked implementation or a runtime-provided function, while genuinely unresolved calls still fail during loading, verification or execution. Runtimes can also add libcalls without coordinating an allowlist change with LLVM.
Code in this change is generated by (an open-weight and self-hosted) LLM, it was agreed on in the Zulip thread [7], where @nagisa volunteered as a reviewer.
Fixes: #165352
[0] llvm/llvm-project@8446b9ffb
[1] llvm/llvm-project#199542
[2] https://github.com/libbpf/libbpf/blob/f7081a/src/libbpf.c#L4345-L4350
[3] https://github.com/aya-rs/aya/blob/15a0de/aya-obj/src/relocation.rs#L606-L614
[4] https://github.com/torvalds/linux/blob/f5bbbfec5/kernel/bpf/verifier.c#L2798-L2800
[5] https://github.com/torvalds/linux/blob/f5bbbfec5/kernel/bpf/verifier.c#L2952-L2958
[6] https://github.com/anza-xyz/sbpf/blob/45bbcb/src/elf.rs#L1223-L1227
[7] https://rust-lang.zulipchat.com/#narrow/channel/606558-llm-reviews/topic/Seeking.20review.20for.20BPF.20bytecode.20linking.20.28issue.20.23135175.29/near/631892496
r? @nagisa