@@ -129,22 +129,24 @@ _LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
129129
130130#if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING)
131131 {
132- // It is only valid to set the IP within the current function.
133- // This is important for ptrauth, otherwise the IP cannot be correctly
134- // signed.
135- // We re-sign to a more usable form and then use it directly.
136- union {
137- unw_word_t opaque_value;
138- unw_word_t
132+ // It is only valid to set the IP within the current function. This is
133+ // important for ptrauth, otherwise the IP cannot be correctly signed.
134+ // The current signature of `value` is via the schema:
135+ // __ptrauth(ptrauth_key_return_address, <<sp>>, 0)
136+ // For this to be generally usable we manually re-sign it to the
137+ // directly supported schema:
138+ // __ptrauth(ptrauth_key_return_address, 1, 0)
139+ unw_word_t
139140 __unwind_ptrauth_restricted_intptr (ptrauth_key_return_address, 1 ,
140141 0 ) authenticated_value;
141- } u;
142- u.opaque_value = (uint64_t )ptrauth_auth_and_resign (
142+ unw_word_t opaque_value = (uint64_t )ptrauth_auth_and_resign (
143143 (void *)value, ptrauth_key_return_address, sp,
144- ptrauth_key_return_address, &u.opaque_value );
145-
146- if (u.authenticated_value < info.start_ip ||
147- u.authenticated_value > info.end_ip )
144+ ptrauth_key_return_address, &authenticated_value);
145+ memmove (reinterpret_cast <void *>(&authenticated_value),
146+ reinterpret_cast <void *>(&opaque_value),
147+ sizeof (authenticated_value));
148+ if (authenticated_value < info.start_ip ||
149+ authenticated_value > info.end_ip )
148150 _LIBUNWIND_ABORT (" PC vs frame info mismatch" );
149151
150152 // PC should have been signed with the sp, so we verify that
0 commit comments