[Pre-RFC] BTF relocations
anakryiko:
It's actually quite common to have
task->se.vruntimeaccesses in C BPF programs, so supporting this from the get go would be essential to make this useful for real-world applications.
Right. I'm not saying that accesses to structures nested by value are uncommon. What I'm saying is that we could roll out experimental nightly-only support for BTF relocations, behind a feature gate, without waiting for const Sized / sized hierarchy to be fully implemented.
That said, I agree that sized hierarchy and support for accesses nested by value would definitely be needed to expose the feature without a gate and on stable Rust.
anakryiko:
Re: naming. "preserve_access_index" naming we use in C is quite opaque and not very meaningful. Everyone just remembered and use it without asking questions, but I always felt like having it named as "btf_relocatable" or something along those lines ("relocatable" is the key here, IMO) would be best. Just my 2 cents on naming.
The more I think about it, the more I'm leaning towards neutral naming not tied to BTF, which could also suit Swift ABI or any other kind of field access relocation. My current implementation touches the field projection logic (compiler/rustc_codegen_ssa/src/mir/place.rs) in MIR in the following way:
github.com/vadorovsky/rust
compiler: Add support for BTF relocations for BPF targets
committed 06:24PM - 27 Apr 26 UTC
vadorovsky
+509 -13
BTF, the BPF Type Format, encodes type information for both the running Linux ke…rnel and compiled eBPF programs. An eBPF object can carry relocation records that describe field and aggregate accesses in terms of BTF types instead of fixed offsets; at load time, the loader compares the program's BTF with the kernel's BTF and rewrites those accesses to the correct offsets for the target kernel. This mechanism is often referred to as "CO-RE relocations" or "BTF relocations". LLVM allows to emit such relocations with the following intrinsics: * @llvm.preserve.array.access.index * @llvm.preserve.struct.access.index * @llvm.preserve.union.access.index When these intrinsics are preserved through codegen, LLVM emits the corresponding relocation records into the BTF.ext ELF section. clang exposes this functionality through __attribute__((preserve_access_index)) that lowers to one of the @llvm.preserve.*.access.index intrinsics, depending on the annotated type. Add corresponding support in Rust with #[relocatable] attribute, hidden behind relocatable_types feature gate
Choosing a target-specific name (bpf_*/btf_*) would mean poisoning this logic with target-specific concepts. It would also require add an another boolean if an another relocation mechanism (e.g. Swift ABI) is added.
Keeping the name neutral keeps MIR target-agnostic and adds only one boolean. Therefore, I would rather call it "relocatable".
anakryiko:
Oh, and I don't know if this is in scope or not, but it would be great to be able to express all of the libbpf/src/bpf_core_read.h at master · libbpf/libbpf · GitHub in Rust through whatever is the most natural way. Checks for type/field existence and enum value retrieval is critical for some real-world applications, not just relocatable field accesses.
Great suggestion. We could add the following Rust intrinsics, which would lower to the following LLVM intrinsics.
With neutral naming, this could eventually be implemented for other relocation mechanisms (e.g. Swift ABI):
relocatable_type_id->llvm.bpf.btf.type.idrelocatable_compare->llvm.bpf.comparerelocatable_getelementptr_and_load->llvm.bpf.getelementptr.and.loadrelocatable_getelementptr_and_store->llvm.bpf.getelementptr.and.storerelocatable_preserve_enum_value->llvm.bpf.preserve.enum.valuerelocatable_preserve_field_info->llvm.bpf.preserve.field.inforelocatable_preserve_type_info->llvm.bpf.preserve.type.info
The following intrinsics, which are of no use outside the BPF context, could carry BPF-specific names:
bpf_load_byte->llvm.bpf.load.bytebpf_load_half->llvm.bpf.load.halfbpf_load_word->llvm.bpf.load.word
Furthermore, once size hierarchy is implemented, the offset_of! macro could lower to relocatable_preserve_field_info for relocatable types.
Discussion in the ATmosphere