@@ -30,6 +30,54 @@ EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, void *, PCONTEXT,
3030                                            _Unwind_Personality_Fn );
3131#endif 
3232
33+ #if  __has_feature (ptrauth_calls )
34+ #include  <ptrauth.h> 
35+ 
36+ // `__ptrauth_restricted_intptr` is a feature of apple clang that predates 
37+ // support for direct application of `__ptrauth` to integer types. This 
38+ // guard is necessary to support compilation with those compiler. 
39+ #if  __has_feature (ptrauth_restricted_intptr_qualifier )
40+ #define  __ptrauth_gcc_personality_intptr (key , addressDiscriminated ,            \
41+                                          discriminator )                        \
42+   __ptrauth_restricted_intptr(key, addressDiscriminated, discriminator)
43+ #else 
44+ #define  __ptrauth_gcc_personality_intptr (key , addressDiscriminated ,            \
45+                                          discriminator )                        \
46+   __ptrauth(key, addressDiscriminated, discriminator)
47+ #endif 
48+ #else 
49+ #define  __ptrauth_gcc_personality_intptr (...)
50+ #endif 
51+ 
52+ #define  __ptrauth_gcc_personality_func_key  ptrauth_key_function_pointer
53+ 
54+ // ptrauth_string_discriminator("__gcc_personality_v0'funcStart") == 0xDFEB 
55+ #define  __ptrauth_gcc_personality_func_start                                    \
56+   __ptrauth_gcc_personality_intptr(__ptrauth_gcc_personality_func_key, 1,      \
57+                                    0xDFEB)
58+ 
59+ // ptrauth_string_discriminator("__gcc_personality_v0'start") == 0x52DC 
60+ #define  __ptrauth_gcc_personality_start                                         \
61+   __ptrauth_gcc_personality_intptr(__ptrauth_gcc_personality_func_key, 1,      \
62+                                    0x52DC)
63+ 
64+ // ptrauth_string_discriminator("__gcc_personality_v0'length") == 0xFFF7 
65+ #define  __ptrauth_gcc_personality_length                                        \
66+   __ptrauth_gcc_personality_intptr(__ptrauth_gcc_personality_func_key, 1,      \
67+                                    0xFFF7)
68+ 
69+ // ptrauth_string_discriminator("__gcc_personality_v0'landingPadOffset") == 
70+ // 0x6498 
71+ #define  __ptrauth_gcc_personality_lpoffset                                      \
72+   __ptrauth_gcc_personality_intptr(__ptrauth_gcc_personality_func_key, 1,      \
73+                                    0x6498)
74+ 
75+ // ptrauth_string_discriminator("__gcc_personality_v0'landingPad") == 0xA134 
76+ #define  __ptrauth_gcc_personality_lpad_disc  0xA134
77+ #define  __ptrauth_gcc_personality_lpad                                          \
78+   __ptrauth_gcc_personality_intptr(__ptrauth_gcc_personality_func_key, 1,      \
79+                                    __ptrauth_gcc_personality_lpad_disc)
80+ 
3381// Pointer encodings documented at: 
3482//   http://refspecs.freestandards.org/LSB_1.3.0/gLSB/gLSB/ehframehdr.html 
3583
@@ -205,7 +253,8 @@ COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_v0(
205253    return  continueUnwind (exceptionObject , context );
206254
207255  uintptr_t  pc  =  (uintptr_t )_Unwind_GetIP (context ) -  1 ;
208-   uintptr_t  funcStart  =  (uintptr_t )_Unwind_GetRegionStart (context );
256+   uintptr_t  __ptrauth_gcc_personality_func_start  funcStart  = 
257+       (uintptr_t )_Unwind_GetRegionStart (context );
209258  uintptr_t  pcOffset  =  pc  -  funcStart ;
210259
211260  // Parse LSDA header. 
@@ -224,11 +273,14 @@ COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_v0(
224273  const  uint8_t  * callSiteTableEnd  =  callSiteTableStart  +  callSiteTableLength ;
225274  const  uint8_t  * p  =  callSiteTableStart ;
226275  while  (p  <  callSiteTableEnd ) {
227-     uintptr_t  start  =  readEncodedPointer (& p , callSiteEncoding );
228-     size_t  length  =  readEncodedPointer (& p , callSiteEncoding );
229-     size_t  landingPad  =  readEncodedPointer (& p , callSiteEncoding );
276+     uintptr_t  __ptrauth_gcc_personality_start  start  = 
277+         readEncodedPointer (& p , callSiteEncoding );
278+     size_t  __ptrauth_gcc_personality_length  length  = 
279+         readEncodedPointer (& p , callSiteEncoding );
280+     size_t  __ptrauth_gcc_personality_lpoffset  landingPadOffset  = 
281+         readEncodedPointer (& p , callSiteEncoding );
230282    readULEB128 (& p ); // action value not used for C code 
231-     if  (landingPad  ==  0 )
283+     if  (landingPadOffset  ==  0 )
232284      continue ; // no landing pad for this entry 
233285    if  ((start  <= pcOffset ) &&  (pcOffset  <  (start  +  length ))) {
234286      // Found landing pad for the PC. 
@@ -238,7 +290,24 @@ COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_v0(
238290      _Unwind_SetGR (context , __builtin_eh_return_data_regno (0 ),
239291                    (uintptr_t )exceptionObject );
240292      _Unwind_SetGR (context , __builtin_eh_return_data_regno (1 ), 0 );
241-       _Unwind_SetIP (context , (funcStart  +  landingPad ));
293+       size_t  __ptrauth_gcc_personality_lpad  landingPad  = 
294+           funcStart  +  landingPadOffset ;
295+ #if  __has_feature (ptrauth_calls )
296+       uintptr_t  stackPointer  =  _Unwind_GetGR (context , -2 );
297+       const  uintptr_t  existingDiscriminator  =  ptrauth_blend_discriminator (
298+           & landingPad , __ptrauth_gcc_personality_lpad_disc );
299+       // newIP is authenticated as if it were qualified with a pseudo qualifier 
300+       // along the lines of: 
301+       //   __ptrauth(ptrauth_key_return_address, <stackPointer>, 0) 
302+       // where the stack pointer is used in place of the strict storage 
303+       // address. 
304+       uintptr_t  newIP  =  (uintptr_t )ptrauth_auth_and_resign (
305+           * (void  * * )& landingPad , __ptrauth_gcc_personality_func_key ,
306+           existingDiscriminator , ptrauth_key_return_address , stackPointer );
307+       _Unwind_SetIP (context , newIP );
308+ #else 
309+       _Unwind_SetIP (context , landingPad );
310+ #endif 
242311      return  _URC_INSTALL_CONTEXT ;
243312    }
244313  }
0 commit comments