@@ -30,6 +30,45 @@ EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, void *, PCONTEXT,
30
30
_Unwind_Personality_Fn );
31
31
#endif
32
32
33
+ #if __has_feature (ptrauth_qualifier )
34
+ #include <ptrauth.h>
35
+ #if __has_feature (ptrauth_restricted_intptr_qualifier )
36
+ #define __ptrauth_gcc_personality_intptr (key , addressDiscriminated , \
37
+ discriminator ) \
38
+ __ptrauth_restricted_intptr(key, addressDiscriminated, discriminator)
39
+ #else
40
+ #define __ptrauth_gcc_personality_intptr (key , addressDiscriminated , \
41
+ discriminator ) \
42
+ __ptrauth(key, addressDiscriminated, discriminator)
43
+ #endif
44
+ #else
45
+ #define __ptrauth_gcc_personality_intptr (...)
46
+ #endif
47
+
48
+ #define __ptrauth_gcc_personality_func_key ptrauth_key_function_pointer
49
+
50
+ // ptrauth_string_discriminator("__gcc_personality_v0'funcStart") == 0xDFEB
51
+ #define __ptrauth_gcc_personality_func_start \
52
+ __ptrauth_gcc_personality_intptr(__ptrauth_gcc_personality_func_key, 1, 0xDFEB)
53
+
54
+ // ptrauth_string_discriminator("__gcc_personality_v0'start") == 0x52DC
55
+ #define __ptrauth_gcc_personality_start \
56
+ __ptrauth_gcc_personality_intptr(__ptrauth_gcc_personality_func_key, 1, 0x52DC)
57
+
58
+ // ptrauth_string_discriminator("__gcc_personality_v0'length") == 0xFFF7
59
+ #define __ptrauth_gcc_personality_length \
60
+ __ptrauth_gcc_personality_intptr(__ptrauth_gcc_personality_func_key, 1, 0xFFF7)
61
+
62
+ // ptrauth_string_discriminator("__gcc_personality_v0'landingPadOffset") == 0x6498
63
+ #define __ptrauth_gcc_personality_lpoffset \
64
+ __ptrauth_gcc_personality_intptr(__ptrauth_gcc_personality_func_key, 1, 0x6498)
65
+
66
+ // ptrauth_string_discriminator("__gcc_personality_v0'landingPad") == 0xA134
67
+ #define __ptrauth_gcc_personality_lpad_disc 0xA134
68
+ #define __ptrauth_gcc_personality_lpad \
69
+ __ptrauth_gcc_personality_intptr(__ptrauth_gcc_personality_func_key, 1, \
70
+ __ptrauth_gcc_personality_lpad_disc)
71
+
33
72
// Pointer encodings documented at:
34
73
// http://refspecs.freestandards.org/LSB_1.3.0/gLSB/gLSB/ehframehdr.html
35
74
@@ -205,7 +244,8 @@ COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_v0(
205
244
return continueUnwind (exceptionObject , context );
206
245
207
246
uintptr_t pc = (uintptr_t )_Unwind_GetIP (context ) - 1 ;
208
- uintptr_t funcStart = (uintptr_t )_Unwind_GetRegionStart (context );
247
+ uintptr_t __ptrauth_gcc_personality_func_start funcStart =
248
+ (uintptr_t )_Unwind_GetRegionStart (context );
209
249
uintptr_t pcOffset = pc - funcStart ;
210
250
211
251
// Parse LSDA header.
@@ -224,11 +264,14 @@ COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_v0(
224
264
const uint8_t * callSiteTableEnd = callSiteTableStart + callSiteTableLength ;
225
265
const uint8_t * p = callSiteTableStart ;
226
266
while (p < callSiteTableEnd ) {
227
- uintptr_t start = readEncodedPointer (& p , callSiteEncoding );
228
- size_t length = readEncodedPointer (& p , callSiteEncoding );
229
- size_t landingPad = readEncodedPointer (& p , callSiteEncoding );
267
+ uintptr_t __ptrauth_gcc_personality_start start =
268
+ readEncodedPointer (& p , callSiteEncoding );
269
+ size_t __ptrauth_gcc_personality_length length =
270
+ readEncodedPointer (& p , callSiteEncoding );
271
+ size_t __ptrauth_gcc_personality_lpoffset landingPadOffset =
272
+ readEncodedPointer (& p , callSiteEncoding );
230
273
readULEB128 (& p ); // action value not used for C code
231
- if (landingPad == 0 )
274
+ if (landingPadOffset == 0 )
232
275
continue ; // no landing pad for this entry
233
276
if ((start <= pcOffset ) && (pcOffset < (start + length ))) {
234
277
// Found landing pad for the PC.
@@ -238,7 +281,28 @@ COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_v0(
238
281
_Unwind_SetGR (context , __builtin_eh_return_data_regno (0 ),
239
282
(uintptr_t )exceptionObject );
240
283
_Unwind_SetGR (context , __builtin_eh_return_data_regno (1 ), 0 );
241
- _Unwind_SetIP (context , (funcStart + landingPad ));
284
+ size_t __ptrauth_gcc_personality_lpad landingPad =
285
+ funcStart + landingPadOffset ;
286
+ #if __has_feature (ptrauth_qualifier )
287
+ uintptr_t stack_pointer = _Unwind_GetGR (context , -2 );
288
+ const uintptr_t existingDiscriminator =
289
+ ptrauth_blend_discriminator (& landingPad ,
290
+ __ptrauth_gcc_personality_lpad_disc );
291
+ // newIP is authenticated as if it were qualified with a pseudo qualifier
292
+ // along the lines of:
293
+ // __ptrauth(ptrauth_key_return_address, <stack_pointer>, 0)
294
+ // where the stack pointer is used in place of the strict storage
295
+ // address.
296
+ uintptr_t newIP =
297
+ (uintptr_t )ptrauth_auth_and_resign (* (void * * )& landingPad ,
298
+ __ptrauth_gcc_personality_func_key ,
299
+ existingDiscriminator ,
300
+ ptrauth_key_return_address ,
301
+ stack_pointer );
302
+ _Unwind_SetIP (context , newIP );
303
+ #else
304
+ _Unwind_SetIP (context , landingPad );
305
+ #endif
242
306
return _URC_INSTALL_CONTEXT ;
243
307
}
244
308
}
0 commit comments