Skip to content

Commit 5818ee3

Browse files
committed
[PAC] Include discriminator in FnAbi, add llvm.ptrauth.resign
This patch introduces the following: * Extends `FnAbi` (`callconv`) with a `ptrauth_type_discriminator` field. This field is only used when emitting pointer authentication call bundles. It is stored in `FnAbi` because the call site is not guaranteed to have access to an `Instance`, so the discriminator cannot always be computed on demand. * Adds support for `llvm.ptrauth.resign`. This intrinsic will be used when support for semantic transmute is added. * Performs a minor API redesign as groundwork for allowing call sites to modify schemas in place.
1 parent 4613587 commit 5818ee3

29 files changed

Lines changed: 165 additions & 24 deletions

compiler/rustc_codegen_gcc/src/builder.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1843,6 +1843,17 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
18431843
fn fptosi_sat(&mut self, val: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> {
18441844
self.fptoint_sat(true, val, dest_ty)
18451845
}
1846+
1847+
fn ptrauth_resign(
1848+
&mut self,
1849+
_value: Self::Value,
1850+
_old_key: u32,
1851+
_old_discriminator: u64,
1852+
_new_key: u32,
1853+
_new_discriminator: u64,
1854+
) -> Self::Value {
1855+
bug!("Resigning of pointers not implemented");
1856+
}
18461857
}
18471858

18481859
impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {

compiler/rustc_codegen_gcc/src/common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> {
323323
cv: Scalar,
324324
layout: abi::Scalar,
325325
ty: Type<'gcc>,
326-
_schema: Option<&PointerAuthSchema>,
326+
_ptrauth_schema: Option<PointerAuthSchema>,
327327
) -> RValue<'gcc> {
328328
let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() };
329329
match cv {

compiler/rustc_codegen_gcc/src/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
405405
fn get_fn_addr(
406406
&self,
407407
instance: Instance<'tcx>,
408-
_pointer_auth_schema: Option<&PointerAuthSchema>,
408+
_ptrauth_schema: Option<PointerAuthSchema>,
409409
) -> RValue<'gcc> {
410410
let func_name = self.tcx.symbol_name(instance).name;
411411

compiler/rustc_codegen_gcc/src/int.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
375375
fixed_count: 3,
376376
conv: CanonAbi::C,
377377
can_unwind: false,
378+
ptrauth_discriminator: 0,
378379
};
379380
fn_abi.adjust_for_foreign_abi(self.cx, ExternAbi::C { unwind: false });
380381

compiler/rustc_codegen_llvm/src/builder.rs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1545,6 +1545,30 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
15451545
let cold_inline = llvm::AttributeKind::Cold.create_attr(self.llcx);
15461546
attributes::apply_to_callsite(llret, llvm::AttributePlace::Function, &[cold_inline]);
15471547
}
1548+
1549+
fn ptrauth_resign(
1550+
&mut self,
1551+
value: &'ll Value,
1552+
old_key: u32,
1553+
old_discriminator: u64,
1554+
new_key: u32,
1555+
new_discriminator: u64,
1556+
) -> &'ll Value {
1557+
let ptr_as_int = self.ptrtoint(value, self.type_i64());
1558+
let resigned_int = self.call_intrinsic(
1559+
"llvm.ptrauth.resign",
1560+
&[],
1561+
&[
1562+
ptr_as_int,
1563+
self.const_i32(old_key as i32),
1564+
self.const_i64(old_discriminator as i64),
1565+
self.const_i32(new_key as i32),
1566+
self.const_i64(new_discriminator as i64),
1567+
],
1568+
);
1569+
1570+
self.inttoptr(resigned_int, self.val_ty(value))
1571+
}
15481572
}
15491573

15501574
impl<'ll> StaticBuilderMethods for Builder<'_, 'll, '_> {
@@ -2163,8 +2187,12 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
21632187
// bundles.
21642188
// Once this is resolved, we should analyze each call and skip direct calls. See the
21652189
// discussion in the rust-lang issue: <https://github.com/rust-lang/rust/issues/152532>
2166-
let key: u32 = 0;
2167-
let discriminator: u64 = 0;
2190+
2191+
let key: u32 = self.sess().pointer_authentication_fn_ptr_key().unwrap() as u32;
2192+
// If sess().pointer_authentication_fn_ptr_type_discrimination() is true, this contains
2193+
// the function pointer type discriminator; otherwise, it is 0.
2194+
let discriminator = fn_abi?.ptrauth_discriminator;
2195+
21682196
Some(llvm::OperandBundleBox::new(
21692197
"ptrauth",
21702198
&[self.const_u32(key), self.const_u64(discriminator)],

compiler/rustc_codegen_llvm/src/common.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,9 @@ pub(crate) fn maybe_sign_fn_ptr<'ll, 'tcx>(
3030
cx: &CodegenCx<'ll, '_>,
3131
instance: Instance<'tcx>,
3232
llfn: &'ll llvm::Value,
33-
schema: &PointerAuthSchema,
33+
ptrauth_schema: PointerAuthSchema,
3434
) -> &'ll llvm::Value {
35-
if cx.tcx.sess.pointer_authentication_functions().is_none() {
36-
return llfn;
37-
}
35+
assert!(cx.tcx.sess.pointer_authentication_functions().is_some());
3836

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

57-
let addr_diversity = match schema.is_address_discriminated {
55+
let addr_diversity = match ptrauth_schema.is_address_discriminated {
5856
PointerAuthAddressDiscriminator::HardwareAddress(true) => Some(llfn),
5957
PointerAuthAddressDiscriminator::HardwareAddress(false) => None,
6058
PointerAuthAddressDiscriminator::Synthetic(val) => {
@@ -63,7 +61,12 @@ pub(crate) fn maybe_sign_fn_ptr<'ll, 'tcx>(
6361
Some(unsafe { llvm::LLVMConstIntToPtr(llval, llty) })
6462
}
6563
};
66-
const_ptr_auth(llfn, schema.key as u32, schema.constant_discriminator as u64, addr_diversity)
64+
const_ptr_auth(
65+
llfn,
66+
ptrauth_schema.key as u32,
67+
ptrauth_schema.constant_discriminator as u64,
68+
addr_diversity,
69+
)
6770
}
6871

6972
/*
@@ -179,11 +182,11 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
179182
&self,
180183
global_alloc: GlobalAlloc<'tcx>,
181184
need_symbol_name: bool,
182-
schema: Option<&PointerAuthSchema>,
185+
ptrauth_schema: Option<PointerAuthSchema>,
183186
) -> Result<&'ll Value, u64> {
184187
let alloc = match global_alloc {
185188
GlobalAlloc::Function { instance, .. } => {
186-
return Ok(self.get_fn_addr(instance, schema));
189+
return Ok(self.get_fn_addr(instance, ptrauth_schema));
187190
}
188191
GlobalAlloc::Static(def_id) => {
189192
assert!(self.tcx.is_static(def_id));
@@ -405,7 +408,7 @@ impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
405408
cv: Scalar,
406409
layout: abi::Scalar,
407410
llty: &'ll Type,
408-
schema: Option<&PointerAuthSchema>,
411+
ptrauth_schema: Option<PointerAuthSchema>,
409412
) -> &'ll Value {
410413
let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() };
411414
match cv {
@@ -422,7 +425,7 @@ impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
422425
let (prov, offset) = ptr.prov_and_relative_offset();
423426
let global_alloc = self.tcx.global_alloc(prov.alloc_id());
424427
let base_addr_space = global_alloc.address_space(self);
425-
let base_addr = match self.alloc_to_backend(global_alloc, false, schema) {
428+
let base_addr = match self.alloc_to_backend(global_alloc, false, ptrauth_schema) {
426429
Ok(base_addr) => base_addr,
427430
Err(base_addr) => {
428431
let val = base_addr.wrapping_add(offset.bytes());

compiler/rustc_codegen_llvm/src/context.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -920,7 +920,7 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
920920
fn get_fn_addr(
921921
&self,
922922
instance: Instance<'tcx>,
923-
pointer_auth_schema: Option<&PointerAuthSchema>,
923+
ptrauth_schema: Option<PointerAuthSchema>,
924924
) -> &'ll Value {
925925
// When pointer authentication metadata is provided, `get_fn_addr` will
926926
// attempt to sign the pointer using LLVM's `ConstPtrAuth` constant
@@ -935,7 +935,7 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
935935
// <https://github.com/rust-lang/rust/issues/152532>, and comment in
936936
// builder's `ptrauth_operand_bundle`.
937937
let llfn = get_fn(self, instance);
938-
match pointer_auth_schema {
938+
match ptrauth_schema {
939939
Some(schema) => common::maybe_sign_fn_ptr(self, instance, llfn, schema),
940940
None => llfn,
941941
}

compiler/rustc_codegen_ssa/src/traits/builder.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,4 +669,13 @@ pub trait BuilderMethods<'a, 'tcx>:
669669
fn zext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
670670

671671
fn apply_attrs_to_cleanup_callsite(&mut self, llret: Self::Value);
672+
673+
fn ptrauth_resign(
674+
&mut self,
675+
value: Self::Value,
676+
old_key: u32,
677+
old_discriminator: u64,
678+
new_key: u32,
679+
new_discriminator: u64,
680+
) -> Self::Value;
672681
}

compiler/rustc_codegen_ssa/src/traits/consts.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub trait ConstCodegenMethods: BackendTypes {
4747
cv: Scalar,
4848
layout: abi::Scalar,
4949
llty: Self::Type,
50-
schema: Option<&PointerAuthSchema>,
50+
ptrauth_schema: Option<PointerAuthSchema>,
5151
) -> Self::Value;
5252

5353
fn const_ptr_byte_offset(&self, val: Self::Value, offset: abi::Size) -> Self::Value;

compiler/rustc_codegen_ssa/src/traits/misc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub trait MiscCodegenMethods<'tcx>: BackendTypes {
2222
fn get_fn_addr(
2323
&self,
2424
instance: Instance<'tcx>,
25-
pointer_auth_schema: Option<&PointerAuthSchema>,
25+
ptrauth_schema: Option<PointerAuthSchema>,
2626
) -> Self::Value;
2727
fn eh_personality(&self) -> Self::Function;
2828
fn sess(&self) -> &Session;

0 commit comments

Comments
 (0)