@@ -8,7 +8,7 @@ pub(crate) mod gpu_offload;
88
99use libc:: { c_char, c_uint} ;
1010use rustc_abi as abi;
11- use rustc_abi:: { Align , Size , WrappingRange } ;
11+ use rustc_abi:: { Align , CanonAbi , Size , WrappingRange } ;
1212use rustc_codegen_ssa:: MemFlags ;
1313use rustc_codegen_ssa:: common:: { IntPredicate , RealPredicate , SynchronizationScope , TypeKind } ;
1414use rustc_codegen_ssa:: mir:: operand:: { OperandRef , OperandValue } ;
@@ -26,7 +26,7 @@ use rustc_sanitizers::{cfi, kcfi};
2626use rustc_session:: config:: OptLevel ;
2727use rustc_span:: Span ;
2828use rustc_target:: callconv:: { FnAbi , PassMode } ;
29- use rustc_target:: spec:: { Arch , HasTargetSpec , SanitizerSet , Target } ;
29+ use rustc_target:: spec:: { Arch , Env , HasTargetSpec , SanitizerSet , Target } ;
3030use smallvec:: SmallVec ;
3131use tracing:: { debug, instrument} ;
3232
@@ -430,6 +430,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
430430 bundles. push ( kcfi_bundle) ;
431431 }
432432
433+ let pauth = self . ptrauth_operand_bundle ( llfn, fn_abi) ;
434+ if let Some ( p) = pauth. as_ref ( ) . map ( |b| b. as_ref ( ) ) {
435+ bundles. push ( p) ;
436+ }
437+
433438 let invoke = unsafe {
434439 llvm:: LLVMBuildInvokeWithOperandBundles (
435440 self . llbuilder ,
@@ -1410,6 +1415,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
14101415 bundles. push ( kcfi_bundle) ;
14111416 }
14121417
1418+ let pauth = self . ptrauth_operand_bundle ( llfn, fn_abi) ;
1419+ if let Some ( p) = pauth. as_ref ( ) . map ( |b| b. as_ref ( ) ) {
1420+ bundles. push ( p) ;
1421+ }
1422+
14131423 let call = unsafe {
14141424 llvm:: LLVMBuildCallWithOperandBundles (
14151425 self . llbuilder ,
@@ -1857,6 +1867,11 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
18571867 bundles. push ( kcfi_bundle) ;
18581868 }
18591869
1870+ let pauth = self . ptrauth_operand_bundle ( llfn, fn_abi) ;
1871+ if let Some ( p) = pauth. as_ref ( ) . map ( |b| b. as_ref ( ) ) {
1872+ bundles. push ( p) ;
1873+ }
1874+
18601875 let callbr = unsafe {
18611876 llvm:: LLVMBuildCallBr (
18621877 self . llbuilder ,
@@ -1976,6 +1991,37 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
19761991 kcfi_bundle
19771992 }
19781993
1994+ // Emits pauth operand bundle.
1995+ fn ptrauth_operand_bundle (
1996+ & mut self ,
1997+ llfn : & ' ll Value ,
1998+ fn_abi : Option < & FnAbi < ' tcx , Ty < ' tcx > > > ,
1999+ ) -> Option < llvm:: OperandBundleBox < ' ll > > {
2000+ if self . sess ( ) . target . env != Env :: Pauthtest {
2001+ return None ;
2002+ }
2003+ // Pauthtest only supports extern "C" calls, filter out other ABIs.
2004+ if fn_abi?. conv != CanonAbi :: C {
2005+ return None ;
2006+ }
2007+ // Filter out LLVM intrinsics.
2008+ if llvm:: get_value_name ( llfn) . starts_with ( b"llvm." ) {
2009+ return None ;
2010+ }
2011+
2012+ // FIXME(jchlanda) operand bundles should only be attached to indirect function calls.
2013+ // However, as function signing is unstable, we end up signing too eagerly (including
2014+ // direct function calls), hence add operand bundles to all calls. We should analyze the
2015+ // call and bail out on direct calls here.
2016+
2017+ let key: u32 = 0 ;
2018+ let discriminator: u64 = 0 ;
2019+ Some ( llvm:: OperandBundleBox :: new (
2020+ "ptrauth" ,
2021+ & [ self . const_u32 ( key) , self . const_u64 ( discriminator) ] ,
2022+ ) )
2023+ }
2024+
19792025 /// Emits a call to `llvm.instrprof.increment`. Used by coverage instrumentation.
19802026 #[ instrument( level = "debug" , skip( self ) ) ]
19812027 pub ( crate ) fn instrprof_increment (
0 commit comments