{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreibqc7vjugt7crdrwhsekwpwkt4et5qgd7bis7szsmu6vwmbcfbc7q",
    "uri": "at://did:plc:ivbknywyskln22er3nkssdhl/app.bsky.feed.post/3mkivvi463542"
  },
  "path": "/t/pre-rfc-btf-relocations/24161?page=2#post_21",
  "publishedAt": "2026-04-27T19:13:34.000Z",
  "site": "https://internals.rust-lang.org",
  "tags": [
    "github.com/vadorovsky/rust",
    "compiler: Add support for BTF relocations for BPF targets",
    "vadorovsky",
    "+509\n-13",
    "",
    "libbpf/src/bpf_core_read.h at master · libbpf/libbpf · GitHub",
    "@llvm.preserve.array.access.index",
    "@llvm.preserve.struct.access.index",
    "@llvm.preserve.union.access.index",
    "@llvm.preserve."
  ],
  "textContent": "anakryiko:\n\n> It's actually quite common to have `task->se.vruntime` accesses in C BPF programs, so supporting this from the get go would be essential to make this useful for real-world applications.\n\nRight. 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.\n\nThat 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.\n\nanakryiko:\n\n> 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.\n\nThe 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:\n\ngithub.com/vadorovsky/rust\n\n####  compiler: Add support for BTF relocations for BPF targets\n\ncommitted 06:24PM - 27 Apr 26 UTC\n\n\n\n          vadorovsky\n        \n\n\n+509\n-13\n\n\nBTF, 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\n\nChoosing 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.\n\nKeeping the name neutral keeps MIR target-agnostic and adds only one boolean. Therefore, I would rather call it \"relocatable\".\n\nanakryiko:\n\n> 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.\n\nGreat suggestion. We could add the following Rust intrinsics, which would lower to the following LLVM intrinsics.\n\nWith neutral naming, this could eventually be implemented for other relocation mechanisms (e.g. Swift ABI):\n\n  * `relocatable_type_id` -> `llvm.bpf.btf.type.id`\n  * `relocatable_compare` -> `llvm.bpf.compare`\n  * `relocatable_getelementptr_and_load` -> `llvm.bpf.getelementptr.and.load`\n  * `relocatable_getelementptr_and_store` -> `llvm.bpf.getelementptr.and.store`\n  * `relocatable_preserve_enum_value` -> `llvm.bpf.preserve.enum.value`\n  * `relocatable_preserve_field_info` -> `llvm.bpf.preserve.field.info`\n  * `relocatable_preserve_type_info` -> `llvm.bpf.preserve.type.info`\n\n\n\nThe following intrinsics, which are of no use outside the BPF context, could carry BPF-specific names:\n\n  * `bpf_load_byte` -> `llvm.bpf.load.byte`\n  * `bpf_load_half` -> `llvm.bpf.load.half`\n  * `bpf_load_word` -> `llvm.bpf.load.word`\n\n\n\nFurthermore, once size hierarchy is implemented, the `offset_of!` macro could lower to `relocatable_preserve_field_info` for relocatable types.",
  "title": "[Pre-RFC] BTF relocations"
}