@@ -4,23 +4,81 @@ use std::borrow::Borrow;
44
55use libc:: { c_char, c_uint} ;
66use rustc_abi:: Primitive :: Pointer ;
7- use rustc_abi:: { self as abi, HasDataLayout as _} ;
7+ use rustc_abi:: { self as abi, ExternAbi , HasDataLayout as _} ;
88use rustc_ast:: Mutability ;
99use rustc_codegen_ssa:: common:: TypeKind ;
1010use rustc_codegen_ssa:: traits:: * ;
1111use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
1212use rustc_hashes:: Hash128 ;
13+ use rustc_hir:: def:: DefKind ;
1314use rustc_hir:: def_id:: DefId ;
1415use rustc_middle:: bug;
1516use rustc_middle:: mir:: interpret:: { GlobalAlloc , PointerArithmetic , Scalar } ;
16- use rustc_middle:: ty:: TyCtxt ;
17+ use rustc_middle:: ty:: { Instance , TyCtxt } ;
1718use rustc_session:: cstore:: DllImport ;
19+ use rustc_target:: spec:: Env ;
1820use tracing:: debug;
1921
20- use crate :: consts:: const_alloc_to_llvm;
22+ use crate :: consts:: { IsInitOrFini , IsStatic , const_alloc_to_llvm} ;
2123pub ( crate ) use crate :: context:: CodegenCx ;
2224use crate :: context:: { GenericCx , SCx } ;
23- use crate :: llvm:: { self , BasicBlock , ConstantInt , FALSE , TRUE , ToLlvmBool , Type , Value } ;
25+ use crate :: llvm:: {
26+ self , BasicBlock , ConstantInt , FALSE , TRUE , ToLlvmBool , Type , Value , const_ptr_auth,
27+ } ;
28+
29+ #[ inline]
30+ pub ( crate ) fn pauth_fn_attrs ( ) -> & ' static [ & ' static str ] {
31+ // FIXME(jchlanda) This is not an exhaustive list of all `pauthtest`-related attributes, but
32+ // only those currently supported. The list is expected to grow as additional functionality is
33+ // implemented, particularly for C++ interoperability.
34+ & [
35+ "aarch64-jump-table-hardening" ,
36+ "ptrauth-indirect-gotos" ,
37+ "ptrauth-calls" ,
38+ "ptrauth-returns" ,
39+ "ptrauth-auth-traps" ,
40+ ]
41+ }
42+
43+ pub ( crate ) fn maybe_sign_fn_ptr < ' ll , ' tcx > (
44+ cx : & CodegenCx < ' ll , ' _ > ,
45+ instance : Instance < ' tcx > ,
46+ llfn : & ' ll llvm:: Value ,
47+ pac : PacMetadata ,
48+ ) -> & ' ll llvm:: Value {
49+ if cx. sess ( ) . target . env != Env :: Pauthtest {
50+ return llfn;
51+ }
52+
53+ // Only free functions or methods
54+ let def_id = instance. def_id ( ) ;
55+ if !matches ! ( cx. tcx. def_kind( def_id) , DefKind :: Fn | DefKind :: AssocFn ) {
56+ return llfn;
57+ }
58+ // Only C ABI
59+ let abi = cx. tcx . fn_sig ( def_id) . skip_binder ( ) . abi ( ) ;
60+ if !matches ! ( abi, ExternAbi :: C { .. } ) {
61+ return llfn;
62+ }
63+ // Ignore LLVM intrinsics
64+ if llvm:: get_value_name ( llfn) . starts_with ( b"llvm." ) {
65+ return llfn;
66+ }
67+ if Some ( def_id) == cx. tcx . lang_items ( ) . eh_personality ( ) {
68+ return llfn;
69+ }
70+
71+ let addr_diversity = match pac. addr_diversity {
72+ AddressDiversity :: None => None ,
73+ AddressDiversity :: Real => Some ( llfn) ,
74+ AddressDiversity :: Synthetic ( val) => {
75+ let llval = cx. const_u64 ( val) ;
76+ let llty = cx. val_ty ( llfn) ;
77+ Some ( unsafe { llvm:: LLVMConstIntToPtr ( llval, llty) } )
78+ }
79+ } ;
80+ const_ptr_auth ( llfn, pac. key , pac. disc , addr_diversity)
81+ }
2482
2583/*
2684* A note on nomenclature of linking: "extern", "foreign", and "upcall".
@@ -264,7 +322,13 @@ impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
264322 } )
265323 }
266324
267- fn scalar_to_backend ( & self , cv : Scalar , layout : abi:: Scalar , llty : & ' ll Type ) -> & ' ll Value {
325+ fn scalar_to_backend_with_pac (
326+ & self ,
327+ cv : Scalar ,
328+ layout : abi:: Scalar ,
329+ llty : & ' ll Type ,
330+ pac : Option < PacMetadata > ,
331+ ) -> & ' ll Value {
268332 let bitsize = if layout. is_bool ( ) { 1 } else { layout. size ( self ) . bits ( ) } ;
269333 match cv {
270334 Scalar :: Int ( int) => {
@@ -293,8 +357,12 @@ impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
293357 self . const_bitcast ( llval, llty)
294358 } ;
295359 } else {
296- let init =
297- const_alloc_to_llvm ( self , alloc. inner ( ) , /*static*/ false ) ;
360+ let init = const_alloc_to_llvm (
361+ self ,
362+ alloc. inner ( ) ,
363+ IsStatic :: No ,
364+ IsInitOrFini :: No ,
365+ ) ;
298366 let alloc = alloc. inner ( ) ;
299367 let value = match alloc. mutability {
300368 Mutability :: Mut => self . static_addr_of_mut ( init, alloc. align , None ) ,
@@ -315,7 +383,7 @@ impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
315383 value
316384 }
317385 }
318- GlobalAlloc :: Function { instance, .. } => self . get_fn_addr ( instance) ,
386+ GlobalAlloc :: Function { instance, .. } => self . get_fn_addr ( instance, pac ) ,
319387 GlobalAlloc :: VTable ( ty, dyn_ty) => {
320388 let alloc = self
321389 . tcx
@@ -326,7 +394,12 @@ impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
326394 } ) ,
327395 ) ) )
328396 . unwrap_memory ( ) ;
329- let init = const_alloc_to_llvm ( self , alloc. inner ( ) , /*static*/ false ) ;
397+ let init = const_alloc_to_llvm (
398+ self ,
399+ alloc. inner ( ) ,
400+ IsStatic :: No ,
401+ IsInitOrFini :: No ,
402+ ) ;
330403 self . static_addr_of_impl ( init, alloc. inner ( ) . align , None )
331404 }
332405 GlobalAlloc :: Static ( def_id) => {
0 commit comments