From d38db07737b54fd29a112491c24d9e206f78de45 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 28 Oct 2026 10:41:28 +0100 Subject: [PATCH 1/2] fix(arm64): unwind past PAC-signed return addresses `strip_pac()` only strips with a mask, and nothing sets one. The `__bionic_clear_pac_bits()` fallback was compiled out because it is not in the NDK, so a signed return address ended the unwind. Strip with `xpaclri` like bionic does, spelled as `hint #7` for assemblers without Armv8.3-A support. It is a NOP on older CPUs. Pixel 8 Pro (Tensor G3, Android 17), `abort()` through two `-mbranch-protection=pac-ret` functions, unwound from a SIGABRT handler like sentry-native's inproc backend. Before: #00 pc 000000000007fdc0 .../libc.so (abort+160) #01 pc 006e8cdf7ce216d0 After: #00 pc 000000000007fdc0 .../libc.so (abort+160) #01 pc 000000000002867c .../pac_test (pac_crash()+12) #02 pc 000000000002868c .../pac_test (pac_caller()+12) #03 pc 0000000000028708 .../pac_test (main+120) #04 pc 000000000007183c .../libc.so (__libc_init+124) Ref: getsentry/sentry-native#2258 --- RegsArm64.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/RegsArm64.cpp b/RegsArm64.cpp index 29c3bd7..a47edf4 100644 --- a/RegsArm64.cpp +++ b/RegsArm64.cpp @@ -67,6 +67,15 @@ static uint64_t strip_pac(uint64_t pc, uint64_t mask) { pc = __bionic_clear_pac_bits(pc); #endif #endif // SENTRY_REMOVED +#ifndef SENTRY_ADDED +#if defined(__aarch64__) + // __bionic_clear_pac_bits() is not in the NDK. Use xpaclri like it does, + // spelled as hint #7 for assemblers without Armv8.3-A support. + register uint64_t x30 __asm("x30") = pc; + asm("hint #7" : "+r"(x30)); + pc = x30; +#endif +#endif // SENTRY_ADDED } return pc; } From 50f66ec36044f45cb3526797790dd8ca80dc1755 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 29 Oct 2026 13:17:06 +0100 Subject: [PATCH 2/2] link to arm developer docs --- RegsArm64.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/RegsArm64.cpp b/RegsArm64.cpp index a47edf4..6b21998 100644 --- a/RegsArm64.cpp +++ b/RegsArm64.cpp @@ -70,7 +70,8 @@ static uint64_t strip_pac(uint64_t pc, uint64_t mask) { #ifndef SENTRY_ADDED #if defined(__aarch64__) // __bionic_clear_pac_bits() is not in the NDK. Use xpaclri like it does, - // spelled as hint #7 for assemblers without Armv8.3-A support. + // spelled as hint #7 for assemblers without Armv8.3-A support: + // https://developer.arm.com/documentation/ddi0602/latest/Base-Instructions/XPACD--XPACI--XPACLRI--Strip-Pointer-Authentication-Code- register uint64_t x30 __asm("x30") = pc; asm("hint #7" : "+r"(x30)); pc = x30;