Skip to content
Open
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 @@ -1843,6 +1843,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
6 changes: 4 additions & 2 deletions compiler/rustc_codegen_gcc/src/common.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use gccjit::{LValue, RValue, ToRValue, Type};
use rustc_abi::Primitive::Pointer;
use rustc_abi::{self as abi, HasDataLayout};
use rustc_abi::{self as abi, HasDataLayout, Size};
use rustc_codegen_ssa::traits::{
BaseTypeCodegenMethods, ConstCodegenMethods, MiscCodegenMethods, StaticCodegenMethods,
};
use rustc_data_structures::fx::FxHashMap;
use rustc_middle::mir::Mutability;
use rustc_middle::mir::interpret::{GlobalAlloc, PointerArithmetic, Scalar};
use rustc_middle::ty::layout::LayoutOf;
Expand Down Expand Up @@ -247,7 +248,8 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> {
cv: Scalar,
layout: abi::Scalar,
ty: Type<'gcc>,
_schema: Option<&PointerAuthSchema>,
_ptrauth_schema: Option<PointerAuthSchema>,
_ptrauth_discriminators: Option<&FxHashMap<Size, u64>>,
) -> 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 @@ -401,7 +401,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: 0,
};
fn_abi.adjust_for_foreign_abi(self.cx, ExternAbi::C { unwind: false });

Expand Down
32 changes: 30 additions & 2 deletions compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1542,6 +1542,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 @@ -2059,8 +2083,12 @@ 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 true, this contains
// the function pointer type discriminator; otherwise, it is 0.
let discriminator = fn_abi?.ptrauth_discriminator;

Some(llvm::OperandBundleBox::new(
"ptrauth",
&[self.const_u32(key), self.const_u64(discriminator)],
Expand Down
27 changes: 18 additions & 9 deletions compiler/rustc_codegen_llvm/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ use std::borrow::Borrow;

use libc::{c_char, c_uint};
use rustc_abi::Primitive::Pointer;
use rustc_abi::{self as abi, ExternAbi, HasDataLayout as _};
use rustc_abi::{self as abi, ExternAbi, HasDataLayout as _, Size};
use rustc_ast::Mutability;
use rustc_codegen_ssa::common::TypeKind;
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hash::{StableHash, StableHasher};
use rustc_hashes::Hash128;
use rustc_hir::def::DefKind;
Expand All @@ -30,11 +31,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 +53,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 +62,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 @@ -317,7 +321,8 @@ impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
cv: Scalar,
layout: abi::Scalar,
llty: &'ll Type,
schema: Option<&PointerAuthSchema>,
ptrauth_schema: Option<PointerAuthSchema>,
ptrauth_discriminators: Option<&FxHashMap<Size, u64>>,
) -> &'ll Value {
let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() };
match cv {
Expand Down Expand Up @@ -352,6 +357,7 @@ impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
alloc.inner(),
IsStatic::No,
IsInitOrFini::No,
ptrauth_discriminators,
);
let alloc = alloc.inner();
let value = match alloc.mutability {
Expand All @@ -373,7 +379,9 @@ impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
value
}
}
GlobalAlloc::Function { instance, .. } => self.get_fn_addr(instance, schema),
GlobalAlloc::Function { instance, .. } => {
self.get_fn_addr(instance, ptrauth_schema)
}
GlobalAlloc::VTable(ty, dyn_ty) => {
let alloc = self
.tcx
Expand All @@ -389,6 +397,7 @@ impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
alloc.inner(),
IsStatic::No,
IsInitOrFini::No,
None,
);
self.static_addr_of_impl(init, alloc.inner().align, None)
}
Expand Down
Loading
Loading