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
11 changes: 11 additions & 0 deletions compiler/rustc_codegen_gcc/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1850,6 +1850,17 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
fn fptosi_sat(&mut self, val: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> {
self.fptoint_sat(true, val, dest_ty)
}

fn ptrauth_resign(
&mut self,
_value: Self::Value,
_old_key: u32,
_old_discriminator: u64,
_new_key: u32,
_new_discriminator: u64,
) -> Self::Value {
bug!("Resigning of pointers not implemented");
}
}

impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_gcc/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> {
cv: Scalar,
layout: abi::Scalar,
ty: Type<'gcc>,
_schema: Option<&PointerAuthSchema>,
_ptrauth_schema: Option<PointerAuthSchema>,
) -> RValue<'gcc> {
let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() };
match cv {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_gcc/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
fn get_fn_addr(
&self,
instance: Instance<'tcx>,
_pointer_auth_schema: Option<&PointerAuthSchema>,
_ptrauth_schema: Option<PointerAuthSchema>,
) -> RValue<'gcc> {
let func_name = self.tcx.symbol_name(instance).name;

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_gcc/src/int.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
fixed_count: 3,
conv: CanonAbi::C,
can_unwind: false,
ptrauth_discriminator: None,
};
fn_abi.adjust_for_foreign_abi(self.cx, ExternAbi::C { unwind: false });

Expand Down
33 changes: 31 additions & 2 deletions compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1553,6 +1553,30 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
let cold_inline = llvm::AttributeKind::Cold.create_attr(self.llcx);
attributes::apply_to_callsite(llret, llvm::AttributePlace::Function, &[cold_inline]);
}

fn ptrauth_resign(
&mut self,
value: &'ll Value,
old_key: u32,
old_discriminator: u64,
new_key: u32,
new_discriminator: u64,
) -> &'ll Value {
let ptr_as_int = self.ptrtoint(value, self.type_i64());
let resigned_int = self.call_intrinsic(
"llvm.ptrauth.resign",
&[],
&[
ptr_as_int,
self.const_i32(old_key as i32),
self.const_i64(old_discriminator as i64),
self.const_i32(new_key as i32),
self.const_i64(new_discriminator as i64),
],
);

self.inttoptr(resigned_int, self.val_ty(value))
}
}

impl<'ll> StaticBuilderMethods for Builder<'_, 'll, '_> {
Expand Down Expand Up @@ -2171,8 +2195,13 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
// 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;

let key: u32 = self.sess().pointer_authentication_fn_ptr_key().unwrap() as u32;
// If sess().pointer_authentication_fn_ptr_type_discrimination() is enabled, this contains
// the function pointer type discriminator; otherwise, it is None. LLVM expects a u64 here,
// so use 0 when no discriminator is present.
let discriminator = fn_abi?.ptrauth_discriminator.unwrap_or(0);

Some(llvm::OperandBundleBox::new(
"ptrauth",
&[self.const_u32(key), self.const_u64(discriminator)],
Expand Down
23 changes: 13 additions & 10 deletions compiler/rustc_codegen_llvm/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,9 @@ pub(crate) fn maybe_sign_fn_ptr<'ll, 'tcx>(
cx: &CodegenCx<'ll, '_>,
instance: Instance<'tcx>,
llfn: &'ll llvm::Value,
schema: &PointerAuthSchema,
ptrauth_schema: PointerAuthSchema,
) -> &'ll llvm::Value {
if cx.tcx.sess.pointer_authentication_functions().is_none() {
return llfn;
}
assert!(cx.tcx.sess.pointer_authentication_functions().is_some());

// Only free functions or methods
let def_id = instance.def_id();
Expand All @@ -54,7 +52,7 @@ pub(crate) fn maybe_sign_fn_ptr<'ll, 'tcx>(
return llfn;
}

let addr_diversity = match schema.is_address_discriminated {
let addr_diversity = match ptrauth_schema.is_address_discriminated {
PointerAuthAddressDiscriminator::HardwareAddress(true) => Some(llfn),
PointerAuthAddressDiscriminator::HardwareAddress(false) => None,
PointerAuthAddressDiscriminator::Synthetic(val) => {
Expand All @@ -63,7 +61,12 @@ pub(crate) fn maybe_sign_fn_ptr<'ll, 'tcx>(
Some(unsafe { llvm::LLVMConstIntToPtr(llval, llty) })
}
};
const_ptr_auth(llfn, schema.key as u32, schema.constant_discriminator as u64, addr_diversity)
const_ptr_auth(
llfn,
ptrauth_schema.key as u32,
ptrauth_schema.constant_discriminator as u64,
addr_diversity,
)
}

/*
Expand Down Expand Up @@ -179,11 +182,11 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
&self,
global_alloc: GlobalAlloc<'tcx>,
need_symbol_name: bool,
schema: Option<&PointerAuthSchema>,
ptrauth_schema: Option<PointerAuthSchema>,
) -> Result<&'ll Value, u64> {
let alloc = match global_alloc {
GlobalAlloc::Function { instance, .. } => {
return Ok(self.get_fn_addr(instance, schema));
return Ok(self.get_fn_addr(instance, ptrauth_schema));
}
GlobalAlloc::Static(def_id) => {
assert!(self.tcx.is_static(def_id));
Expand Down Expand Up @@ -405,7 +408,7 @@ impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
cv: Scalar,
layout: abi::Scalar,
llty: &'ll Type,
schema: Option<&PointerAuthSchema>,
ptrauth_schema: Option<PointerAuthSchema>,
) -> &'ll Value {
let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() };
match cv {
Expand All @@ -422,7 +425,7 @@ impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
let (prov, offset) = ptr.prov_and_relative_offset();
let global_alloc = self.tcx.global_alloc(prov.alloc_id());
let base_addr_space = global_alloc.address_space(self);
let base_addr = match self.alloc_to_backend(global_alloc, false, schema) {
let base_addr = match self.alloc_to_backend(global_alloc, false, ptrauth_schema) {
Ok(base_addr) => base_addr,
Err(base_addr) => {
let val = base_addr.wrapping_add(offset.bytes());
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,7 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn get_fn_addr(
&self,
instance: Instance<'tcx>,
pointer_auth_schema: Option<&PointerAuthSchema>,
ptrauth_schema: Option<PointerAuthSchema>,
) -> &'ll Value {
// When pointer authentication metadata is provided, `get_fn_addr` will
// attempt to sign the pointer using LLVM's `ConstPtrAuth` constant
Expand All @@ -953,7 +953,7 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
// <https://github.com/rust-lang/rust/issues/152532>, and comment in
// builder's `ptrauth_operand_bundle`.
let llfn = get_fn(self, instance);
match pointer_auth_schema {
match ptrauth_schema {
Some(schema) => common::maybe_sign_fn_ptr(self, instance, llfn, schema),
None => llfn,
}
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_codegen_ssa/src/traits/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -671,4 +671,13 @@ pub trait BuilderMethods<'a, 'tcx>:
fn zext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;

fn apply_attrs_to_cleanup_callsite(&mut self, llret: Self::Value);

fn ptrauth_resign(
&mut self,
value: Self::Value,
old_key: u32,
old_discriminator: u64,
new_key: u32,
new_discriminator: u64,
) -> Self::Value;
}
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/traits/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub trait ConstCodegenMethods: BackendTypes {
cv: Scalar,
layout: abi::Scalar,
llty: Self::Type,
schema: Option<&PointerAuthSchema>,
ptrauth_schema: Option<PointerAuthSchema>,
) -> Self::Value;

fn const_ptr_byte_offset(&self, val: Self::Value, offset: abi::Size) -> Self::Value;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/traits/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub trait MiscCodegenMethods<'tcx>: BackendTypes {
fn get_fn_addr(
&self,
instance: Instance<'tcx>,
pointer_auth_schema: Option<&PointerAuthSchema>,
ptrauth_schema: Option<PointerAuthSchema>,
) -> Self::Value;
fn eh_personality(&self) -> Self::Function;
fn sess(&self) -> &Session;
Expand Down
25 changes: 21 additions & 4 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ pub enum PointerAuthARM8_3Key {
}

/// Forms of extra discrimination.
#[derive(Clone, Debug, PartialEq)]
pub enum PointerAuthDiscrimination {
/// No additional discrimination.
None,
Expand All @@ -107,6 +108,7 @@ pub enum PointerAuthDiscrimination {
}

/// Types of address discrimination.
#[derive(Clone, Debug)]
pub enum PointerAuthAddressDiscriminator {
/// Enable/disable hardware address discrimination.
HardwareAddress(bool),
Expand All @@ -115,6 +117,7 @@ pub enum PointerAuthAddressDiscriminator {
Synthetic(u64),
}

#[derive(Clone, Debug)]
pub struct PointerAuthSchema {
pub is_address_discriminated: PointerAuthAddressDiscriminator,
pub discrimination_kind: PointerAuthDiscrimination,
Expand Down Expand Up @@ -1185,12 +1188,26 @@ impl Session {
self.pointer_auth_config.is_some()
}

pub fn pointer_authentication_functions(&self) -> Option<&PointerAuthSchema> {
self.pointer_auth_config.as_ref().and_then(|cfg| cfg.function_pointers.as_ref())
pub fn pointer_authentication_functions(&self) -> Option<PointerAuthSchema> {
self.pointer_auth_config.as_ref().and_then(|cfg| cfg.function_pointers.clone())
}

pub fn pointer_authentication_init_fini(&self) -> Option<&PointerAuthSchema> {
self.pointer_auth_config.as_ref().and_then(|cfg| cfg.init_fini.as_ref())
pub fn pointer_authentication_init_fini(&self) -> Option<PointerAuthSchema> {
self.pointer_auth_config.as_ref().and_then(|cfg| cfg.init_fini.clone())
}

pub fn pointer_authentication_fn_ptr_type_discrimination(&self) -> bool {
self.pointer_auth_config
.as_ref()
.and_then(|cfg| cfg.function_pointers.as_ref())
.is_some_and(|schema| schema.discrimination_kind == PointerAuthDiscrimination::Type)
}

pub fn pointer_authentication_fn_ptr_key(&self) -> Option<PointerAuthARM8_3Key> {
self.pointer_auth_config
.as_ref()
.and_then(|cfg| cfg.function_pointers.as_ref())
.map(|schema| schema.key)
}
}

Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_target/src/callconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -625,19 +625,23 @@ pub struct FnAbi<'a, Ty> {
pub conv: CanonAbi,
/// Indicates if an unwind may happen across a call to this function.
pub can_unwind: bool,
/// Computed type discriminator for pointer authentication purpose.
pub ptrauth_discriminator: Option<u64>,
}

// Needs to be a custom impl because of the bounds on the `TyAndLayout` debug impl.
impl<'a, Ty: fmt::Display> fmt::Debug for FnAbi<'a, Ty> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let FnAbi { args, ret, c_variadic, fixed_count, conv, can_unwind } = self;
let FnAbi { args, ret, c_variadic, fixed_count, conv, can_unwind, ptrauth_discriminator } =
self;
f.debug_struct("FnAbi")
.field("args", args)
.field("ret", ret)
.field("c_variadic", c_variadic)
.field("fixed_count", fixed_count)
.field("conv", conv)
.field("can_unwind", can_unwind)
.field("ptrauth_discriminator", ptrauth_discriminator)
.finish()
}
}
Expand Down Expand Up @@ -950,6 +954,6 @@ mod size_asserts {
use super::*;
// tidy-alphabetical-start
static_assert_size!(ArgAbi<'_, usize>, 56);
static_assert_size!(FnAbi<'_, usize>, 80);
static_assert_size!(FnAbi<'_, usize>, 96);
// tidy-alphabetical-end
}
6 changes: 6 additions & 0 deletions compiler/rustc_ty_utils/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use rustc_hir::attrs::lang_items::LangItem;
use rustc_hir::{self as hir, find_attr};
use rustc_middle::bug;
use rustc_middle::middle::deduced_param_attrs::DeducedParamAttrs;
use rustc_middle::ptrauth::ptrauth_compute_fn_ptr_type_discriminator_for;
use rustc_middle::query::Providers;
use rustc_middle::ty::layout::{
FnAbiError, HasTyCtxt, HasTypingEnv, LayoutCx, LayoutOf, TyAndLayout, fn_can_unwind,
Expand Down Expand Up @@ -611,6 +612,11 @@ fn fn_abi_new_uncached<'tcx>(
determined_fn_def_id,
sig.abi(),
),
ptrauth_discriminator: if tcx.sess.pointer_authentication_fn_ptr_type_discrimination() {
Some(ptrauth_compute_fn_ptr_type_discriminator_for(tcx, sig).unwrap_or(0).into())
} else {
None
},
};
fn_abi_adjust_for_abi(cx, &mut fn_abi, sig.abi());
debug!("fn_abi_new_uncached = {:?}", fn_abi);
Expand Down
1 change: 1 addition & 0 deletions tests/ui/abi/c-zst.aarch64-darwin.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
fixed_count: 1,
conv: C,
can_unwind: false,
ptrauth_discriminator: None,
}
--> $DIR/c-zst.rs:65:1
|
Expand Down
1 change: 1 addition & 0 deletions tests/ui/abi/c-zst.powerpc-linux.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
fixed_count: 1,
conv: C,
can_unwind: false,
ptrauth_discriminator: None,
}
--> $DIR/c-zst.rs:65:1
|
Expand Down
1 change: 1 addition & 0 deletions tests/ui/abi/c-zst.s390x-linux.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
fixed_count: 1,
conv: C,
can_unwind: false,
ptrauth_discriminator: None,
}
--> $DIR/c-zst.rs:65:1
|
Expand Down
1 change: 1 addition & 0 deletions tests/ui/abi/c-zst.sparc64-linux.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
fixed_count: 1,
conv: C,
can_unwind: false,
ptrauth_discriminator: None,
}
--> $DIR/c-zst.rs:65:1
|
Expand Down
1 change: 1 addition & 0 deletions tests/ui/abi/c-zst.x86_64-linux.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
fixed_count: 1,
conv: C,
can_unwind: false,
ptrauth_discriminator: None,
}
--> $DIR/c-zst.rs:65:1
|
Expand Down
1 change: 1 addition & 0 deletions tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
fixed_count: 1,
conv: C,
can_unwind: false,
ptrauth_discriminator: None,
}
--> $DIR/c-zst.rs:65:1
|
Expand Down
Loading
Loading