@@ -129,14 +129,28 @@ _LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
129
129
pint_t sp = (pint_t )co->getReg (UNW_REG_SP);
130
130
131
131
#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
-
139
132
{
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
+
140
154
// PC should have been signed with the sp, so we verify that
141
155
// roundtripping does not fail.
142
156
pint_t pc = (pint_t )co->getReg (UNW_REG_IP);
0 commit comments