Skip to content

Commit ace40a9

Browse files
committed
PR feedback: minicore, LLVMRustConstPtrAuth and in-code docs
1 parent d46b4bd commit ace40a9

8 files changed

Lines changed: 72 additions & 35 deletions

File tree

compiler/rustc_codegen_llvm/src/context.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,18 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
851851
}
852852

853853
fn get_fn_addr(&self, instance: Instance<'tcx>, pac: Option<PacMetadata>) -> &'ll Value {
854+
// When pointer authentication metadata is provided, `get_fn_addr` will
855+
// attempt to sign the pointer using LLVM's `ConstPtrAuth` constant
856+
// expression.
857+
//
858+
// FIXME(jchlanda) Currently, all function addresses requested from
859+
// within LLVM codegen are signed. This behavior is too broad, resulting
860+
// in the logic being applied to function values, not just pointers
861+
// (addresses).
862+
//
863+
// See the discussion in the rust-lang issue:
864+
// <https://github.com/rust-lang/rust/issues/152532>, and comment in
865+
// builder's `ptrauth_operand_bundle`.
854866
let llfn = get_fn(self, instance);
855867
match pac {
856868
Some(pac) => common::maybe_sign_fn_ptr(self, instance, llfn, pac),

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2586,9 +2586,9 @@ unsafe extern "C" {
25862586
) -> &'ll Value;
25872587

25882588
pub(crate) fn LLVMRustConstPtrAuth(
2589-
ptr: *mut Value,
2589+
ptr: *const Value,
25902590
key: u32,
25912591
disc: u64,
2592-
addr_diversity: *mut Value,
2593-
) -> *mut Value;
2592+
addr_diversity: *const Value,
2593+
) -> *const Value;
25942594
}

compiler/rustc_codegen_llvm/src/llvm/mod.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -484,10 +484,8 @@ pub(crate) fn const_ptr_auth<'ll>(
484484
addr_diversity: Option<&'ll Value>,
485485
) -> &'ll Value {
486486
unsafe {
487-
let addr_div_ptr = addr_diversity.map_or(std::ptr::null_mut(), |v| v as *const _ as *mut _);
488-
489-
let result = LLVMRustConstPtrAuth(ptr as *const _ as *mut _, key, disc, addr_div_ptr);
490-
487+
let addr_div_ptr = addr_diversity.map_or(std::ptr::null(), |v| v as *const Value);
488+
let result = LLVMRustConstPtrAuth(ptr as *const Value, key, disc, addr_div_ptr);
491489
&*result
492490
}
493491
}

compiler/rustc_codegen_ssa/src/traits/misc.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ use rustc_session::Session;
77
use super::BackendTypes;
88

99
/// Strategy for incorporating address-based diversity into PAC computation.
10+
#[derive(Default)]
1011
pub enum AddressDiversity {
1112
/// No address diversity is applied.
13+
#[default]
1214
None,
1315
/// Use the actual memory address for diversification.
1416
Real,
@@ -17,12 +19,6 @@ pub enum AddressDiversity {
1719
Synthetic(u64),
1820
}
1921

20-
impl Default for AddressDiversity {
21-
fn default() -> Self {
22-
AddressDiversity::None
23-
}
24-
}
25-
2622
/// Metadata used for pointer authentication.
2723
pub struct PacMetadata {
2824
/// The PAC key to use.

tests/assembly-llvm/targets/targets-aarch64_unknown_linux_pauthtest.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,43 @@
1+
//@ add-minicore
12
//@ assembly-output: emit-asm
23
//@ only-aarch64-unknown-linux-pauthtest
34
//@ revisions: aarch64_unknown_linux_pauthtest
45
//@ [aarch64_unknown_linux_pauthtest] compile-flags: --target=aarch64-unknown-linux-pauthtest
56
//@ [aarch64_unknown_linux_pauthtest] needs-llvm-components: aarch64
67

8+
#![feature(no_core, lang_items)]
79
#![no_std]
10+
#![no_core]
811
#![crate_type = "lib"]
912

13+
extern crate minicore;
14+
1015
#[no_mangle]
1116
#[inline(never)]
12-
pub extern "C" fn add(a: i32, b: i32) -> i32 {
13-
a + b
17+
pub extern "C" fn c_func(a: i32) -> i32 {
18+
a
1419
}
1520

1621
#[no_mangle]
1722
#[inline(never)]
18-
fn call_through(f: extern "C" fn(i32, i32) -> i32, x: i32) -> i32 {
19-
f(x, 1)
23+
fn call_through(f: extern "C" fn(i32) -> i32, x: i32) -> i32 {
24+
f(x)
2025
}
2126

2227
#[no_mangle]
2328
#[inline(never)]
24-
pub fn call_add(x: i32) -> i32 {
25-
call_through(add, x)
29+
pub fn call_c_func(x: i32) -> i32 {
30+
call_through(c_func, x)
2631
}
2732

2833
// CHECK-LABEL: call_through:
2934
// CHECK: mov [[PTR:x[0-9]+]], x0
3035
// CHECK: mov w0, w1
31-
// CHECK: mov w1, #1
3236
// CHECK: braaz [[PTR]]
3337

34-
// CHECK-LABEL: call_add:
35-
// CHECK: adrp [[GOT_REG:x[0-9]+]], :got:add
36-
// CHECK: ldr [[GOT_REG]], [[[GOT_REG]], :got_lo12:add]
38+
// CHECK-LABEL: call_c_func:
39+
// CHECK: adrp [[GOT_REG:x[0-9]+]], :got:c_func
40+
// CHECK: ldr [[GOT_REG]], [[[GOT_REG]], :got_lo12:c_func]
3741
// CHECK: paciza [[FN_REG:x[0-9]+]]
3842
// CHECK: mov w1, w0
3943
// CHECK: mov x0, [[FN_REG]]

tests/auxiliary/minicore.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,12 +282,16 @@ impl<T, const N: usize> Sync for [T; N] {}
282282

283283
// Function pointers are treated as `Sync` to match real `core` behavior.
284284
//
285-
// We intentionally only cover the zero-argument form since tests using this minicore
286-
// are simplified to `fn() -> R` / `extern "C" fn() -> R` to avoid arity-specific
287-
// complexity. See: tests/codegen-llvm/pauth-extern-weak-global.rs for the use case.
285+
// Minicore provides only the minimal set of impls required by tests. Rather
286+
// than exhaustively covering all possible function pointer signatures,
287+
// additional impls should be added as needed.
288288
impl<R> Sync for fn() -> R {}
289+
impl<R> Sync for extern "C" fn() -> R {}
289290
impl<R> Sync for unsafe extern "C" fn() -> R {}
290291

292+
impl<A, R> Sync for extern "C" fn(A) -> R {}
293+
impl<A, R> Sync for unsafe extern "C" fn(A) -> R {}
294+
291295
#[lang = "drop_in_place"]
292296
fn drop_in_place<T>(_: *mut T) {}
293297

@@ -355,6 +359,16 @@ pub mod ptr {
355359
}
356360
}
357361

362+
pub mod hint {
363+
#[inline]
364+
pub fn black_box<T>(dummy: T) -> T {
365+
#[rustc_intrinsic]
366+
fn black_box<T>(dummy: T) -> T;
367+
368+
unsafe { black_box(dummy) }
369+
}
370+
}
371+
358372
#[lang = "c_void"]
359373
#[repr(u8)]
360374
pub enum c_void {

tests/codegen-llvm/pauth/pauth-extern-c-direct-indirect-call.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//@ add-minicore
12
// ignore-tidy-linelength
23
//@ only-aarch64-unknown-linux-pauthtest
34
//@ revisions: O0_PAUTH O3_PAUTH
@@ -9,11 +10,17 @@
910

1011
// Make sure that direct extern "C" calls are not handled by pointer authentication operand bundle
1112
// logic.
12-
use std::ffi::c_void;
13-
use std::hint::black_box;
13+
#![feature(no_core, lang_items)]
14+
#![no_std]
15+
#![no_core]
16+
#![crate_type = "lib"]
17+
18+
extern crate minicore;
19+
use minicore::hint::black_box;
20+
use minicore::*;
1421

1522
extern "C" {
16-
fn rand() -> i32;
23+
fn rand() -> bool;
1724
fn add(a: i32, b: i32) -> i32;
1825
fn sub(a: i32, b: i32) -> i32;
1926

@@ -43,9 +50,9 @@ fn test_indirect_call() {
4350

4451
// Also test calling via conditional pointer
4552
unsafe {
46-
// O0_PAUTH: call {{.*}}i32 ptrauth (ptr @rand, i32 0)({{.*}}) #{{[0-9]+}} [ "ptrauth"(i32 0, i64 0) ]
47-
// O3_PAUTH: call {{.*}}i32 @rand() #
48-
let use_add = rand() % 2 == 0;
53+
// O0_PAUTH: call {{.*}}i1 ptrauth (ptr @rand, i32 0)({{.*}}) #{{[0-9]+}} [ "ptrauth"(i32 0, i64 0) ]
54+
// O3_PAUTH: call {{.*}}i1 @rand() #
55+
let use_add = rand();
4956
// O0_PAUTH: store ptr ptrauth (ptr @sub, i32 0), ptr %[[FP_O0:[a-zA-Z0-9_.]+]]
5057
// O0_PAUTH: store ptr ptrauth (ptr @add, i32 0), ptr %[[FP_O0]]{{.*}}
5158
// O0_PAUTH: %[[LOAD_FP_O0:[a-zA-Z0-9_.]+]] = load ptr, ptr %[[FP_O0]]{{.*}}
@@ -61,7 +68,7 @@ fn test_indirect_call() {
6168
}
6269
}
6370

64-
// CHECK-LABE: test_direct_call
71+
// CHECK-LABEL: test_direct_call
6572
#[inline(never)]
6673
fn test_direct_call() {
6774
unsafe {
@@ -78,7 +85,7 @@ fn test_direct_call() {
7885
}
7986
}
8087

81-
fn main() {
88+
pub fn entry() {
8289
test_indirect_call();
8390
test_direct_call();
8491
}

tests/codegen-llvm/pauth/pauth-init-fini.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//@ add-minicore
12
// ignore-tidy-linelength
23
//@ only-aarch64-unknown-linux-pauthtest
34
//@ revisions: O0_PAUTH O3_PAUTH
@@ -9,8 +10,13 @@
910

1011
// Make sure that init/fini metadata uses correct discriminator: 0xd9d4/55764
1112

13+
#![feature(no_core, lang_items)]
14+
#![no_std]
15+
#![no_core]
1216
#![crate_type = "lib"]
13-
#![feature(linkage)]
17+
18+
extern crate minicore;
19+
use minicore::*;
1420

1521
// O0_PAUTH: @{{[0-9A-Za-z_]+}}GLOBAL_INIT = constant ptr ptrauth (ptr @{{[0-9A-Za-z_]+}}init_fn, i32 0, i64 55764, ptr inttoptr (i64 1 to ptr)), section ".init_array.90"
1622
// O3_PAUTH: @{{[0-9A-Za-z_]+}}GLOBAL_INIT = constant ptr ptrauth (ptr @{{[0-9A-Za-z_]+}}init_fn, i32 0, i64 55764, ptr inttoptr (i64 1 to ptr)), section ".init_array.90"

0 commit comments

Comments
 (0)