Add BTF relocation builtins - #161107
Add BTF relocation builtins#161107vadorovsky wants to merge 5 commits into
Conversation
|
Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt This PR changes MIR cc @oli-obk, @RalfJung, @JakobDegen, @vakaras Some changes occurred to constck cc @fee1-dead
cc @Amanieu, @folkertdev, @sayantn This PR changes rustc_public cc @oli-obk, @celinval, @ouz-a, @makai410 Some changes occurred to the CTFE machinery Some changes occurred in compiler/rustc_passes/src/check_attr.rs cc @jdonszelmann, @JonathanBrouwer
cc @bjorn3 Some changes occurred in match checking cc @Nadrieril Some changes occurred in compiler/rustc_attr_parsing cc @jdonszelmann, @JonathanBrouwer Some changes occurred in compiler/rustc_attr_ir cc @jdonszelmann, @JonathanBrouwer Some changes occurred in cc @BoxyUwU The parser was modified, potentially altering the grammar of (stable) Rust cc @fmease Some changes occurred to the CTFE / Miri interpreter cc @rust-lang/miri |
This comment has been minimized.
This comment has been minimized.
Sorry, I will trim this PR only to the builtins. They can be still tested with minicore and a macro embedded in test. And I'm going to leave the core_arch change for later. |
7de4ec2 to
869a54b
Compare
This comment has been minimized.
This comment has been minimized.
|
Now CI fails on |
869a54b to
b42b869
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| Reborrow(Ty<'tcx>, Mutability, Place<'tcx>), | ||
|
|
||
| /// Queries BTF metadata for a statically resolved field path. | ||
| BtfFieldInfo { base_ty: Ty<'tcx>, path: Box<[BtfFieldStep<'tcx>]>, kind: BtfFieldInfoKind }, |
There was a problem hiding this comment.
This is a very unusual MIR construct, to put it quite mildly. Please add a bit more detail. What is this "metadata" that is being queried and how is it returned? What are the validity conditions? When is this operation UB (if ever)?
We usually work very hard to keep target-specific things away from this core part of the compiler, so seeing BTF-specific things here is somewhat alarming.
There was a problem hiding this comment.
Also, please write comments in this part in the compiler assuming that the reader never heard of BTF or BPF before. So, always include a link for such acronyms.
There was a problem hiding this comment.
We usually work very hard to keep target-specific things away from this core part of the compiler, so seeing BTF-specific things here is somewhat alarming.
I hear you. Given that the other field relocation mechanisms (like Swift ABI reslence, Objective-C ivars etc.) could potentially reuse this construct, I will try to come up with some neutral name. Would that be satisfactory for you?
There was a problem hiding this comment.
That's not where I was going. :) I am not asking for overeager generalization, we can always rename stuff later if it becomes more generally useful.
What I was going for with the second paragraph in my comment is: does this have to be a primitive MIR statement? Why is there no less invasive way to do this?
There was a problem hiding this comment.
Can this for example be an intrinsic (core::intrinsics::btf_field_info(...))?
| Self::ByteOffset => 0, | ||
| Self::ByteSize => 1, | ||
| Self::Exists => 2, |
There was a problem hiding this comment.
Where do these constants come from? Can rustc just do whatever it wants here or are these magic constants defined by some outside protocol?
There was a problem hiding this comment.
They are defined by LLVM in https://github.com/llvm/llvm-project/blob/llvmorg-23.1.1/llvm/include/llvm/DebugInfo/BTF/BTF.h#L280-L296
I added only these 3 variants, because they are sufficient for basic field relocations to work. I was thinking about following up with the rest of relocation types later.
There was a problem hiding this comment.
We should definitely not have any values defined by LLVM in rustc_middle. This is backend-agonstic code. LLVM-specific consts can only be used in the LLVM backend.
There was a problem hiding this comment.
Sorry, I wasn't exactly right in my last comment - these values are not limited to LLVM, they're honored in Linux kernel headers as well:
https://elixir.bootlin.com/linux/v7.2.5/source/include/uapi/linux/bpf.h#L7616
And they are used in the binary relocation records that are present in BPF object files. So I think these variant IDs can be treated as universal for BPF, not LLVM-specific.
That said, I can try avoiding to use them in MIR.
| } | ||
|
|
||
| BtfFieldInfo { .. } => { | ||
| throw_unsup_format!("BTF field relocation queries cannot be interpreted"); |
There was a problem hiding this comment.
FWIW Miri will probably eventually want to support these, so for stabilization we need to consider what to do. But for now this is fine.
| (unstable, bpf_target_feature, "1.54.0", Some(150247)), | ||
| // no-tracking-issue-start | ||
| /// Allows BTF CO-RE field relocation queries. | ||
| (unstable, btf_relocations, "CURRENT_RUSTC_VERSION", None), |
There was a problem hiding this comment.
You do have a tracking issue though...?
b42b869 to
3dea160
Compare
|
Register the unstable `btf_relocations` feature and add the `#[btf_relocatable]` built-in attribute for structs and unions, that can be used only on BPF architecture. Preserve the attribute in crate metadata, add UI coverage for feature gating and attribute target validation.
Reject field projection and `offset_off!` usage on `#[btf_relocatable]` types.
Add builtin macros for requesting BTF field information from the Rust compiler's frontend perspective: * `btf_field_byte_offset` * `btf_field_byte_size` * `btf_field_exists` Parse them as `BtfFieldInfo` expressions that carry the kind of requested information (offset, size, exists), base type and the field path. This mechanism supports nested field accesses in one query. Add internal compiler intrinsics corresponding to LLVM's and GCC's BTF preservation intrinsics: * `btf_preserve_access_index` * `btf_preserve_field_info` Lower the builtin macros to calls to these intrinsics. Add corresponding methods to the `BuilderMethods` trait in codegen SSA and use them for lowering the intrinsic calls. Backends without BTF relocation support report an error. Support in backends will be added in follow-up changes. This change does not expose the functionality to the users. A user-facing API will also be added in a follow-up change.
Expose wrappers for the `llvm.preserve.struct.access.index` and
`llvm.preserve.union.access.index` intrinsics.
Lower backend-neutral BTF field paths by mapping Rust field indices to
LLVM aggregate indices and emitting the corresponding intrinsic calls
(`llvm.preserve.{struct,union}.access.index`). Pass the resulting field
pointer to `llvm.bpf.preserve.field.info`.
Test the `btf_field_exists`, `btf_field_byte_offset` and `btf_field_byte_size` builtins and make sure they emit correct LLVM intrinsic calls.
3dea160 to
2a1be29
Compare
Add experimental Rust support for Compile Once, Run Everywhere (CO-RE) relocations based on the BPF Type Format (BTF). The entire feature is specific to the BPF architecture and cannot be used elsewhere. The feature introduces a
#[btf_relocatable]attribute for structs and unions whose field layout must be queried through BTF-aware operations, and adds BTF-aware bultins:btf_field_existsbtf_field_byte_offsetbtf_field_byte_sizeThis PR does not yet expose these builtins to the users, the
core_archAPI will be added as a follow-up change.The user-facing feature is gated by
#![feature(btf_relocations)].See individual commits for details.
Created with the help of an LLM, initially used to analyze the existing MIR, codegen SSA and LLVM backend code, to help identifying which parts of code need modification. Afterwards, the code and commit messages were written by hand, then reviewed by an LLM.
Tracking issue: #160616
RFC: rust-lang/rfcs#3966
r? @traviscross @nagisa