@@ -129,14 +129,28 @@ _LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
129129 pint_t sp = (pint_t )co->getReg (UNW_REG_SP);
130130
131131#if __has_feature(ptrauth_calls)
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- [[maybe_unused]]unw_word_t stripped_value =
136- (unw_word_t )ptrauth_strip ((void *)value, ptrauth_key_return_address);
137- assert (stripped_value >= info.start_ip && stripped_value <= info.end_ip );
138-
139132 {
133+ // It is only valid to set the IP within the current function.
134+ // This is important for ptrauth, otherwise the IP cannot be correctly
135+ // signed.
136+ // We re-sign to a more usable form and then use it directly.
137+ union {
138+ unw_word_t opaque_value;
139+ unw_word_t
140+ __unwind_ptrauth_restricted_intptr (ptrauth_key_return_address, 1 , 0 )
141+ authenticated_value;
142+ } u;
143+ u.opaque_value = (uint64_t )ptrauth_auth_and_resign (
144+ (void *)value,
145+ ptrauth_key_return_address,
146+ getSP (),
147+ ptrauth_key_return_address,
148+ &u.opaque_value );
149+
150+ if (u.authenticated_value < info.start_ip ||
151+ u.authenticated_value > info.end_ip )
152+ _LIBUNWIND_ABORT (" PC vs frame info mismatch" );
153+
140154 // PC should have been signed with the sp, so we verify that
141155 // roundtripping does not fail.
142156 pint_t pc = (pint_t )co->getReg (UNW_REG_IP);
0 commit comments