Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
dbc4eb8
Introduce `aarch64-unknown-linux-pauthtest`
jchlanda Apr 3, 2026
844c6f4
New signature of `get_fn_addr`, teach Rust how to sign fn pointers
jchlanda Apr 3, 2026
8eccfb1
Add pauth attributes and first IR tests
jchlanda Apr 3, 2026
157212b
Add support for init/fini signing and correctly sign extern weak globals
jchlanda Apr 3, 2026
7669c44
Teach bootstrap how to build rust_test_helpers for pauthtest
jchlanda Apr 3, 2026
05a389d
Override static libraries and warn on linking against that kind of libs
jchlanda Apr 29, 2026
128d77d
Correctly set f128 math support for pauthtest
jchlanda May 5, 2026
b8198cc
Use target_env = "musl" & target_abi = "pauthtest"
jchlanda May 11, 2026
4ee476c
PR feedback: Introduce
jchlanda Jun 1, 2026
9da0a3b
PR feedback: Attributes
jchlanda Jun 1, 2026
124bfe4
PR feedback: Init/Fini
jchlanda Jun 1, 2026
23a7ecb
PR feedback: Teach bootstrap
jchlanda Jun 1, 2026
88fe032
PR feedback: Override static
jchlanda Jun 1, 2026
52ccc75
PR feedback: Use target_env
jchlanda Jun 1, 2026
f31f522
Support DefKind::InlineConst in UnevaluatedConst
khyperia Jun 27, 2026
9aaea56
Recover deferred closure calls after errors
Dnreikronos Jun 27, 2026
bd938c5
Include default-stability info in rustdoc JSON.
obi1kenobi Jun 27, 2026
e101c8d
tests: check wasm compiler_builtins object architecture
Vastargazing May 6, 2026
5128fcb
Note where and why documentation hard-links are used
bushrat011899 Jun 29, 2026
91a762b
Inline information of whether this segment is delegation's child segm…
aerooneqq Jun 29, 2026
cd55f64
fix typo in `-Z min-recursion-limit` unstable doc
lqd Jun 29, 2026
a60be48
llvm-wrapper: use accessors for private fields in LLVM 23+
liza371 Jun 29, 2026
7bfdb60
Comment on needed RAM in huge-stacks.rs
workingjubilee Jun 29, 2026
abbfd2c
Pass the whole `GenericArgs` to `Interner::for_each_relevant_impl()`
ChayimFriedman2 May 7, 2026
67b5ab7
Rollup merge of #155722 - jchlanda:jakub/pac, r=davidtwco
JonathanBrouwer Jun 30, 2026
5aa6dfb
Rollup merge of #156230 - Vastargazing:tests/wasm-compiler-builtins-o…
JonathanBrouwer Jun 30, 2026
38c8bac
Rollup merge of #156295 - ChayimFriedman2:for-each-impl-args, r=lcnr
JonathanBrouwer Jun 30, 2026
0c58e97
Rollup merge of #158375 - khyperia:inline-consts-in-type-system, r=Bo…
JonathanBrouwer Jun 30, 2026
1d86eaa
Rollup merge of #158556 - aerooneqq:delegation-child-segment-perf, r=…
JonathanBrouwer Jun 30, 2026
b198035
Rollup merge of #158081 - Dnreikronos:trait_system/deferred_closure_r…
JonathanBrouwer Jun 30, 2026
244d5c2
Rollup merge of #158468 - obi1kenobi:pg/default-body-stability, r=Gui…
JonathanBrouwer Jun 30, 2026
3277200
Rollup merge of #158543 - bushrat011899:core_io_hard_linked_docs, r=M…
JonathanBrouwer Jun 30, 2026
bc08a26
Rollup merge of #158564 - lqd:fix-doc, r=Kivooeo
JonathanBrouwer Jun 30, 2026
aa4c911
Rollup merge of #158568 - liza371:llvm-23-compat, r=nikic
JonathanBrouwer Jun 30, 2026
9779110
Rollup merge of #158582 - workingjubilee:add-comment-to-huge-stacks.r…
JonathanBrouwer Jun 30, 2026
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
7 changes: 6 additions & 1 deletion compiler/rustc_ast_lowering/src/delegation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::symbol::kw;
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol};

use crate::delegation::generics::{GenericsGenerationResult, GenericsGenerationResults};
use crate::delegation::generics::{
GenericsGenerationResult, GenericsGenerationResults, GenericsPosition,
};
use crate::diagnostics::{
CycleInDelegationSignatureResolution, DelegationAttemptedBlockWithDefsDeletion,
DelegationBlockSpecifiedWhenNoParams, UnresolvedDelegationCallee,
Expand Down Expand Up @@ -505,6 +507,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
res: Res::Local(param_id),
args: None,
infer_args: false,
delegation_child_segment: false,
}));

let path = self.arena.alloc(hir::Path { span, res: Res::Local(param_id), segments });
Expand Down Expand Up @@ -714,6 +717,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
result.args_segment_id = segment.hir_id;
result.use_for_sig_inheritance = !result.generics.is_trait_impl();

segment.delegation_child_segment = result.generics.pos() == GenericsPosition::Child;

segment
}

Expand Down
12 changes: 10 additions & 2 deletions compiler/rustc_ast_lowering/src/delegation/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use rustc_span::{Ident, Span, sym};
use crate::LoweringContext;
use crate::diagnostics::DelegationInfersMismatch;

#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub(super) enum GenericsPosition {
Parent,
Child,
Expand Down Expand Up @@ -155,7 +155,7 @@ impl<'hir> DelegationGenericArgsIterator<'hir> {
impl<'hir> HirOrTyGenerics<'hir> {
pub(super) fn into_hir_generics(&mut self, ctx: &mut LoweringContext<'_, 'hir>, span: Span) {
if let HirOrTyGenerics::Ty(ty) = self {
let rename_self = matches!(ty.pos, GenericsPosition::Child);
let rename_self = ty.pos == GenericsPosition::Child;
let params = ctx.uplift_delegation_generic_params(span, &ty.data, rename_self);

*self = HirOrTyGenerics::Hir(DelegationGenerics {
Expand Down Expand Up @@ -218,6 +218,13 @@ impl<'hir> HirOrTyGenerics<'hir> {
.expect("`Self` generic param is not found while expected"),
}
}

pub(crate) fn pos(&self) -> GenericsPosition {
match self {
HirOrTyGenerics::Ty(ty) => ty.pos,
HirOrTyGenerics::Hir(hir) => hir.pos,
}
}
}

impl<'hir> GenericsGenerationResult<'hir> {
Expand Down Expand Up @@ -590,6 +597,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
ident: p.name.ident(),
infer_args: false,
res,
delegation_child_segment: false,
}]),
res,
span: p.span,
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1014,6 +1014,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
res,
args,
infer_args: args.is_none(),
delegation_child_segment: false,
}]),
})
}
Expand Down Expand Up @@ -2791,7 +2792,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
ExprKind::ConstBlock(anon_const) => {
let def_id = self.local_def_id(anon_const.id);
assert_eq!(DefKind::AnonConst, self.tcx.def_kind(def_id));
assert_eq!(DefKind::InlineConst, self.tcx.def_kind(def_id));
self.lower_anon_const_to_const_arg(anon_const, span)
}
_ => overly_complex_const(self),
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast_lowering/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
} else {
Some(generic_args.into_generic_args(self))
},
delegation_child_segment: false,
}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/universal_regions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {

BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(..) => {
match tcx.def_kind(self.mir_def) {
DefKind::InlineConst => {
DefKind::InlineConst if !tcx.is_type_system_inline_const(self.mir_def) => {
// This is required for `AscribeUserType` canonical query, which will call
// `type_of(inline_const_def_id)`. That `type_of` would inject erased lifetimes
// into borrowck, which is ICE #78174.
Expand Down
13 changes: 10 additions & 3 deletions compiler/rustc_codegen_gcc/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use gccjit::{LValue, RValue, ToRValue, Type};
use rustc_abi::Primitive::Pointer;
use rustc_abi::{self as abi, HasDataLayout};
use rustc_codegen_ssa::traits::{
BaseTypeCodegenMethods, ConstCodegenMethods, MiscCodegenMethods, StaticCodegenMethods,
BaseTypeCodegenMethods, ConstCodegenMethods, MiscCodegenMethods, PacMetadata,
StaticCodegenMethods,
};
use rustc_middle::mir::Mutability;
use rustc_middle::mir::interpret::{GlobalAlloc, PointerArithmetic, Scalar};
Expand Down Expand Up @@ -241,7 +242,13 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> {
None
}

fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, ty: Type<'gcc>) -> RValue<'gcc> {
fn scalar_to_backend_with_pac(
&self,
cv: Scalar,
layout: abi::Scalar,
ty: Type<'gcc>,
_pac: Option<PacMetadata>,
) -> RValue<'gcc> {
let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() };
match cv {
Scalar::Int(int) => {
Expand Down Expand Up @@ -290,7 +297,7 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> {
}
value
}
GlobalAlloc::Function { instance, .. } => self.get_fn_addr(instance),
GlobalAlloc::Function { instance, .. } => self.get_fn_addr(instance, None),
GlobalAlloc::VTable(ty, dyn_ty) => {
let alloc = self
.tcx
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_codegen_gcc/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ use gccjit::{Block, CType, Context, Function, FunctionType, LValue, Location, RV
use rustc_abi::{Align, HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx};
use rustc_codegen_ssa::base::wants_msvc_seh;
use rustc_codegen_ssa::errors as ssa_errors;
use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeCodegenMethods, MiscCodegenMethods};
use rustc_codegen_ssa::traits::{
BackendTypes, BaseTypeCodegenMethods, MiscCodegenMethods, PacMetadata,
};
use rustc_data_structures::base_n::{ALPHANUMERIC_ONLY, ToBaseN};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_middle::mir::interpret::Allocation;
Expand Down Expand Up @@ -398,7 +400,7 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
get_fn(self, instance)
}

fn get_fn_addr(&self, instance: Instance<'tcx>) -> RValue<'gcc> {
fn get_fn_addr(&self, instance: Instance<'tcx>, _pac: Option<PacMetadata>) -> RValue<'gcc> {
let func_name = self.tcx.symbol_name(instance).name;

let func = if let Some(variable) = self.get_declared_value(func_name) {
Expand Down
11 changes: 10 additions & 1 deletion compiler/rustc_codegen_llvm/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ use rustc_session::config::{
};
use rustc_span::sym;
use rustc_symbol_mangling::mangle_internal_symbol;
use rustc_target::spec::{Arch, FramePointer, SanitizerSet, StackProbeType, StackProtector};
use rustc_target::spec::{
Arch, FramePointer, LlvmAbi, SanitizerSet, StackProbeType, StackProtector,
};
use smallvec::SmallVec;

use crate::common::pauth_fn_attrs;
use crate::context::SimpleCx;
use crate::errors::{PackedStackBackchainNeedsSoftfloat, SanitizerMemtagRequiresMte};
use crate::llvm::AttributePlace::Function;
Expand Down Expand Up @@ -643,6 +646,12 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
}
}

if sess.target.llvm_abiname == LlvmAbi::Pauthtest {
for &ptrauth_attr in pauth_fn_attrs() {
to_add.push(llvm::CreateAttrString(cx.llcx, ptrauth_attr));
}
}

to_add.extend(target_features_attr(cx, tcx, function_features));

attributes::apply_to_llfn(llfn, Function, &to_add);
Expand Down
40 changes: 38 additions & 2 deletions compiler/rustc_codegen_llvm/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@ use rustc_middle::mono::Visibility;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::{DebugInfo, Offload};
use rustc_span::Symbol;
use rustc_target::spec::SanitizerSet;
use rustc_target::spec::{LlvmAbi, SanitizerSet};

use super::ModuleLlvm;
use crate::attributes;
use crate::builder::Builder;
use crate::builder::gpu_offload::OffloadGlobals;
use crate::common::pauth_fn_attrs;
use crate::context::CodegenCx;
use crate::llvm::{self, Value};

Expand Down Expand Up @@ -123,7 +124,18 @@ pub(crate) fn compile_codegen_unit(
if let Some(entry) =
maybe_create_entry_wrapper::<Builder<'_, '_, '_>>(&cx, cx.codegen_unit)
{
let attrs = attributes::sanitize_attrs(&cx, tcx, SanitizerFnAttrs::default());
let mut attrs = attributes::sanitize_attrs(&cx, tcx, SanitizerFnAttrs::default());
// When pointer authentication is enabled, ensure that the ptrauth-* attributes are
// also attached to the entry wrapper.
//
// FIXME(jchlanda) If it ever becomes necessary to ensure that all compiler
// generated functions receive the ptrauth-* attributes, `declare_fn` or
// `declare_raw_fn` could be used to provide those.
if cx.sess().target.llvm_abiname == LlvmAbi::Pauthtest {
for &ptrauth_attr in pauth_fn_attrs() {
attrs.push(llvm::CreateAttrString(cx.llcx, ptrauth_attr));
}
}
attributes::apply_to_llfn(entry, llvm::AttributePlace::Function, &attrs);
}

Expand All @@ -140,6 +152,30 @@ pub(crate) fn compile_codegen_unit(
cx.add_objc_module_flags();
}

if cx.sess().target.llvm_abiname == LlvmAbi::Pauthtest {
// FIXME(jchlanda): In LLVM/Clang, there are also `aarch64-elf-pauthabi-platform`
// and `aarch64-elf-pauthabi-version` module flags. These are emitted into the
// PAuth core info section of the resulting ELF, which the linker uses to enforce
// binary compatibility.
//
// We intentionally do not emit these flags now, since only a subset of features
// included in clang's pauthtest is currently supported. By default, the absence of
// this info is treated as compatible with any binary.
//
// Please note, that this would cause compatibility issues, specifically runtime
// crashes due to authentication failures (while compiling and linking
// successfully) when linking against binaries that support larger set of features
// (for example, signing of C++ member function pointers, virtual function
// pointers, virtual table pointers).
//
// Link to PAuth core info documentation:
// <https://github.com/ARM-software/abi-aa/blob/2025Q4/pauthabielf64/pauthabielf64.rst#core-information>
if cx.sess().opts.unstable_opts.ptrauth_elf_got {
cx.add_ptrauth_elf_got_flag();
}
cx.add_ptrauth_sign_personality_flag();
}

// Finalize code coverage by injecting the coverage map. Note, the coverage map will
// also be added to the `llvm.compiler.used` variable, created next.
if cx.sess().instrument_coverage() {
Expand Down
53 changes: 51 additions & 2 deletions compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub(crate) mod autodiff;
pub(crate) mod gpu_offload;

use libc::{c_char, c_uint};
use rustc_abi::{self as abi, Align, Size, WrappingRange};
use rustc_abi::{self as abi, Align, CanonAbi, Size, WrappingRange};
use rustc_codegen_ssa::MemFlags;
use rustc_codegen_ssa::common::{IntPredicate, RealPredicate, SynchronizationScope, TypeKind};
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
Expand All @@ -26,7 +26,7 @@ use rustc_sanitizers::{cfi, kcfi};
use rustc_session::config::OptLevel;
use rustc_span::Span;
use rustc_target::callconv::{FnAbi, PassMode};
use rustc_target::spec::{Arch, HasTargetSpec, SanitizerSet, Target};
use rustc_target::spec::{Arch, HasTargetSpec, LlvmAbi, SanitizerSet, Target};
use smallvec::SmallVec;
use tracing::{debug, instrument};

Expand Down Expand Up @@ -475,6 +475,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
bundles.push(kcfi_bundle);
}

let pauth = self.ptrauth_operand_bundle(llfn, fn_abi);
if let Some(p) = pauth.as_ref().map(|b| b.as_ref()) {
bundles.push(p);
}

let invoke = unsafe {
llvm::LLVMBuildInvokeWithOperandBundles(
self.llbuilder,
Expand Down Expand Up @@ -1472,6 +1477,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
bundles.push(kcfi_bundle);
}

let pauth = self.ptrauth_operand_bundle(llfn, fn_abi);
if let Some(p) = pauth.as_ref().map(|b| b.as_ref()) {
bundles.push(p);
}

let call = unsafe {
llvm::LLVMBuildCallWithOperandBundles(
self.llbuilder,
Expand Down Expand Up @@ -1902,6 +1912,11 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
bundles.push(kcfi_bundle);
}

let pauth = self.ptrauth_operand_bundle(llfn, fn_abi);
if let Some(p) = pauth.as_ref().map(|b| b.as_ref()) {
bundles.push(p);
}

let callbr = unsafe {
llvm::LLVMBuildCallBr(
self.llbuilder,
Expand Down Expand Up @@ -2021,6 +2036,40 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
kcfi_bundle
}

// Emits pauth operand bundle.
fn ptrauth_operand_bundle(
&mut self,
llfn: &'ll Value,
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
) -> Option<llvm::OperandBundleBox<'ll>> {
if self.sess().target.llvm_abiname != LlvmAbi::Pauthtest {
return None;
}
// Pointer authentication support is currently limited to extern "C" calls; filter out other
// ABIs.
if fn_abi?.conv != CanonAbi::C {
return None;
}
// Filter out LLVM intrinsics.
if llvm::get_value_name(llfn).starts_with(b"llvm.") {
return None;
}

// FIXME(jchlanda) Operand bundles should only be attached to indirect function calls.
// However, function pointer signing is currently performed in `get_fn_addr`, which causes
// the logic to be applied too broadly, including to function values (not just pointers).
// As a result, direct calls using signed function values must also receive operand
// bundles.
// Once this is resolved, we should analyze each call and skip direct calls. See the
// discussion in the rust-lang issue: <https://github.com/rust-lang/rust/issues/152532>
let key: u32 = 0;
let discriminator: u64 = 0;
Some(llvm::OperandBundleBox::new(
"ptrauth",
&[self.const_u32(key), self.const_u64(discriminator)],
))
}

/// Emits a call to `llvm.instrprof.increment`. Used by coverage instrumentation.
#[instrument(level = "debug", skip(self))]
pub(crate) fn instrprof_increment(
Expand Down
Loading
Loading