Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1624,6 +1624,7 @@ impl Expr {
| ExprKind::While(..)
| ExprKind::Yield(YieldKind::Postfix(..))
| ExprKind::DirectConstArg(..)
| ExprKind::BtfFieldInfo(..)
| ExprKind::Err(_)
| ExprKind::Dummy => prefix_attrs_precedence(&self.attrs),
}
Expand Down Expand Up @@ -1923,6 +1924,9 @@ pub enum ExprKind {
/// An mGCA `direct_const_arg!()` expression.
DirectConstArg(Box<Expr>),

/// A BTF field metadata query.
BtfFieldInfo(BtfRelocKind, Box<Ty>, ThinVec<Ident>),

/// Placeholder for an expression that wasn't syntactically well formed in some way.
Err(ErrorGuaranteed),

Expand Down Expand Up @@ -2195,6 +2199,44 @@ impl YieldKind {
}
}

/// The kind of [BPF Type Format (BTF)][btf] relocation.
///
/// [BTF][btf] is the type metadata format used by the Linux kernel and eBPF
/// tooling for relocations: the compiled program records which field or array
/// element it intended to access, and the loader rewrites the bytecode to
/// match the layout of the kernel it is about to run on.
///
/// The following variants are a subset of the relocation kinds defined by
/// Linux's [`bpf_core_relo_kind`].
///
/// [btf]: https://docs.kernel.org/bpf/btf.html
/// [`bpf_core_relo_kind`]: https://docs.kernel.org/bpf/llvm_reloc.html#relocation-kinds
#[derive(Clone, Copy, Encodable, Decodable, Debug, Eq, PartialEq, StableHash, Walkable)]
pub enum BtfRelocKind {
/// Offset of the field.
ByteOffset,
/// Size of the field.
ByteSize,
/// Whether the field exists.
Exists,
}

impl BtfRelocKind {
pub fn as_str(&self) -> &'static str {
match self {
Self::ByteOffset => "btf_field_byte_offset",
Self::ByteSize => "btf_field_byte_size",
Self::Exists => "btf_field_exists",
}
}
}

impl fmt::Display for BtfRelocKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.as_str().fmt(f)
}
}

/// A literal in a meta item.
#[derive(Clone, Copy, Encodable, Decodable, Debug, StableHash)]
pub struct MetaItemLit {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_ast/src/util/classify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ pub fn leading_labeled_expr(mut expr: &ast::Expr) -> bool {
| Yield(..)
| UnsafeBinderCast(..)
| DirectConstArg(..)
| BtfFieldInfo(..)
| Err(..)
| Dummy => return false,
}
Expand Down Expand Up @@ -218,7 +219,7 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<TrailingBrace<'_>> {
break (mac.args.delim == Delimiter::Brace).then_some(TrailingBrace::MacCall(mac));
}

InlineAsm(_) | OffsetOf(_, _) | IncludedBytes(_) | FormatArgs(_) => {
InlineAsm(_) | OffsetOf(_, _) | IncludedBytes(_) | FormatArgs(_) | BtfFieldInfo(..) => {
// These should have been denied pre-expansion.
break None;
}
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,7 @@ macro_rules! common_visitor_and_walkers {
BoundAsyncness,
BoundConstness,
BoundPolarity,
BtfRelocKind,
ByRef,
Closure,
Const,
Expand Down Expand Up @@ -1114,6 +1115,8 @@ macro_rules! common_visitor_and_walkers {
visit_visitable!(vis, kind, expr, ty),
ExprKind::DirectConstArg(expr) =>
visit_visitable!(vis, expr),
ExprKind::BtfFieldInfo(kind, container, fields) =>
visit_visitable!(vis, kind, container, fields),
ExprKind::Err(_guar) => {}
ExprKind::Dummy => {}
}
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
let e = self.emit_bad_direct_const_arg(e.span, expr, "expression");
hir::ExprKind::Err(e)
}

ExprKind::BtfFieldInfo(kind, container, fields) => hir::ExprKind::BtfFieldInfo(
*kind,
self.lower_ty_alloc(
container,
ImplTraitContext::Disallowed(ImplTraitPosition::BtfFieldInfo),
),
self.arena.alloc_from_iter(fields.iter().map(|&ident| self.lower_ident(ident))),
),
};

hir::Expr { hir_id: expr_hir_id, kind, span }
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,7 @@ enum ImplTraitPosition {
Cast,
ImplSelf,
OffsetOf,
BtfFieldInfo,
}

impl std::fmt::Display for ImplTraitPosition {
Expand All @@ -554,6 +555,7 @@ impl std::fmt::Display for ImplTraitPosition {
ImplTraitPosition::Cast => "cast expression types",
ImplTraitPosition::ImplSelf => "impl headers",
ImplTraitPosition::OffsetOf => "`offset_of!` parameters",
ImplTraitPosition::BtfFieldInfo => "BTF field info query parameters",
};

write!(f, "{name}")
Expand Down
18 changes: 18 additions & 0 deletions compiler/rustc_ast_pretty/src/pprust/state/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,24 @@ impl<'a> State<'a> {
self.print_expr(expr, FixupContext::default());
self.pclose()
}
ast::ExprKind::BtfFieldInfo(kind, container, fields) => {
self.word("builtin # ");
self.word(kind.as_str());
self.popen();
let ib = self.ibox(0);
self.print_type(container);
self.word(",");
self.space();
if let Some((&first, rest)) = fields.split_first() {
self.print_ident(first);
for &field in rest {
self.word(".");
self.print_ident(field);
}
}
self.end(ib);
self.pclose();
}
}

self.ann.post(self, AnnNode::Expr(expr));
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_attr_ir/src/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,9 @@ pub enum AttributeKind {
/// Represents `#[automatically_derived]`
AutomaticallyDerived,

/// Represents `#[btf_relocatable]`.
BtfRelocatable(Span),

/// Represents the trace attribute of `#[cfg_attr]`
CfgAttrTrace(ThinVec<(CfgEntry, Span)>),

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_attr_ir/src/encode_cross_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ impl AttributeKind {
AllowInternalUnstable(..) => Yes,
AlwaysGca => Yes,
AutomaticallyDerived => Yes,
BtfRelocatable(..) => Yes,
CfgAttrTrace(..) => Yes,
CfgTrace(..) => Yes,
CfiEncoding { .. } => Yes,
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_attr_ir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,12 @@ language_item_table! {

// Experimental lang item for `Reflection and comptime`(https://goals.rust-lang.org/2025h2/reflection-and-comptime.html)
FnPtr, sym::FnPtr, fn_ptr, Target::Struct, GenericRequirement::None;

// Experimental lang items for BTF CO-RE relocations.
BtfPreserveAccessIndex, sym::btf_preserve_access_index, btf_preserve_access_index, Target::Fn, GenericRequirement::Exact(1);
BtfPreserveFieldByteOffset, sym::btf_preserve_field_byte_offset, btf_preserve_field_byte_offset, Target::Fn, GenericRequirement::Exact(0);
BtfPreserveFieldByteSize, sym::btf_preserve_field_byte_size, btf_preserve_field_byte_size, Target::Fn, GenericRequirement::Exact(0);
BtfPreserveFieldExists, sym::btf_preserve_field_exists, btf_preserve_field_exists, Target::Fn, GenericRequirement::Exact(0);
}

/// The requirement imposed on the generics of a lang item
Expand Down
22 changes: 22 additions & 0 deletions compiler/rustc_attr_parsing/src/attributes/btf_relocatable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use rustc_feature::AttributeStability;
use rustc_target::spec::Arch;

use super::prelude::*;
use crate::diagnostics::BtfRelocatableOnNonBpfArch;

pub(crate) struct BtfRelocatableParser;

impl NoArgsAttributeParser for BtfRelocatableParser {
const PATH: &[Symbol] = &[sym::btf_relocatable];
const ALLOWED_TARGETS: AllowedTargets<'_> =
AllowedTargets::AllowList(&[Allow(Target::Struct), Allow(Target::Union)]);
const STABILITY: AttributeStability = unstable!(btf_relocations);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::BtfRelocatable;

fn finalize_check(cx: &FinalizeCheckContext<'_, '_>, attr_span: Span) {
// `#[btf_relocatable]` may be only applied on BPF architecture.
if cx.shared.cx.sess().target.arch != Arch::Bpf {
cx.shared.cx.dcx().emit_err(BtfRelocatableOnNonBpfArch { span: attr_span });
}
}
}
1 change: 1 addition & 0 deletions compiler/rustc_attr_parsing/src/attributes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ mod prelude;
pub(crate) mod allow_unstable;
pub(crate) mod autodiff;
pub(crate) mod body;
pub(crate) mod btf_relocatable;
pub(crate) mod cfg;
pub(crate) mod cfg_select;
pub(crate) mod cfi_encoding;
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol};
use crate::attributes::allow_unstable::*;
use crate::attributes::autodiff::*;
use crate::attributes::body::*;
use crate::attributes::btf_relocatable::*;
use crate::attributes::cfi_encoding::*;
use crate::attributes::codegen_attrs::*;
use crate::attributes::confusables::*;
Expand Down Expand Up @@ -261,6 +262,7 @@ attribute_parsers!(
Single<WithoutArgs<AllowInternalUnsafeParser>>,
Single<WithoutArgs<AlwaysGcaParser>>,
Single<WithoutArgs<AutomaticallyDerivedParser>>,
Single<WithoutArgs<BtfRelocatableParser>>,
Single<WithoutArgs<ColdParser>>,
Single<WithoutArgs<CompilerBuiltinsParser>>,
Single<WithoutArgs<ComptimeParser>>,
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_attr_parsing/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2056,3 +2056,10 @@ pub(crate) struct UnusedDuplicate {
)]
pub warning: bool,
}

#[derive(Diagnostic)]
#[diag("the `btf_relocatable` attribute can only be used on BPF architecture")]
pub(crate) struct BtfRelocatableOnNonBpfArch {
#[primary_span]
pub span: Span,
}
3 changes: 2 additions & 1 deletion compiler/rustc_builtin_macros/src/assert/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,8 @@ impl<'cx, 'a> Context<'cx, 'a> {
| ExprKind::Become(_)
| ExprKind::Yield(_)
| ExprKind::DirectConstArg(_)
| ExprKind::UnsafeBinderCast(..) => {}
| ExprKind::UnsafeBinderCast(..)
| ExprKind::BtfFieldInfo(..) => {}
}
}

Expand Down
Loading
Loading