@@ -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