@@ -89,6 +89,34 @@ const UNWIND_DATA_REG: (i32, i32) = (10, 11); // x10, x11
8989#[ cfg( any( target_arch = "loongarch32" , target_arch = "loongarch64" ) ) ]
9090const UNWIND_DATA_REG : ( i32 , i32 ) = ( 4 , 5 ) ; // a0, a1
9191
92+ unsafe fn sign_lpad ( context : * mut uw:: _Unwind_Context , lpad : * const u8 ) -> * const u8 {
93+ cfg_select ! {
94+ all( target_env = "pauthtest" , target_arch = "aarch64" ) => {
95+ // DWARF register number for SP on AArch64.
96+ const SP_REG : i32 = 31 ;
97+
98+ unsafe {
99+ let sp = uw:: _Unwind_GetGR( context, SP_REG ) as u64 ;
100+ let mut addr = lpad as usize ;
101+
102+ // `pacib` corresponds to `ptrauth_key_process_dependent_code` in <ptrauth.h>.
103+ core:: arch:: asm!(
104+ "pacib {addr}, {sp}" ,
105+ addr = inout( reg) addr,
106+ sp = in( reg) sp,
107+ options( nostack, preserves_flags)
108+ ) ;
109+
110+ lpad. with_addr( addr)
111+ }
112+ }
113+ _ => {
114+ let _ = context;
115+ lpad
116+ }
117+ }
118+ }
119+
92120// The following code is based on GCC's C and C++ personality routines. For reference, see:
93121// https://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_personality.cc
94122// https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c
@@ -239,7 +267,8 @@ cfg_select! {
239267 exception_object. cast( ) ,
240268 ) ;
241269 uw:: _Unwind_SetGR( context, UNWIND_DATA_REG . 1 , core:: ptr:: null( ) ) ;
242- uw:: _Unwind_SetIP( context, lpad) ;
270+ let maybe_signed_lpad = sign_lpad( context, lpad) ;
271+ uw:: _Unwind_SetIP( context, maybe_signed_lpad) ;
243272 uw:: _URC_INSTALL_CONTEXT
244273 }
245274 EHAction :: Terminate => uw:: _URC_FATAL_PHASE2_ERROR,
0 commit comments