From 000af9a1646ebc8c2b8120b60a2946d9718a3072 Mon Sep 17 00:00:00 2001 From: Julian Schroeder Date: Mon, 30 Oct 2023 11:43:42 -0600 Subject: [PATCH] [stacktrace_generic_fp] clear aarch64 pointer auth bits AARCH64 >= armv8.3-a supports pointer authentication. If this feature is enabled it modifies the previously unused upper address bits in apointer. The affected bits need to be cleared in order for stacktrace to work. Signed-off-by: Aliaksey Kandratsenka [alkondratenko@gmail.com: added succinct subject line] --- src/stacktrace_generic_fp-inl.h | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/stacktrace_generic_fp-inl.h b/src/stacktrace_generic_fp-inl.h index 91fedef..f7f5af3 100644 --- a/src/stacktrace_generic_fp-inl.h +++ b/src/stacktrace_generic_fp-inl.h @@ -77,6 +77,27 @@ namespace stacktrace_generic_fp { #define PAD_FRAME #endif +#if __aarch64__ +// Aarch64 has pointer authentication and uses the upper 16bit of a stack +// or return address to sign it. These bits needs to be strip in order for +// stacktraces to work. +void *strip_PAC(void* _ptr) { + void *ret; + asm volatile( + "mov x30, %1\n\t" + "hint #7\n\t" // xpaclri, is NOP for < armv8.3-a + "mov %0, x30\n\t" + : "=r"(ret) + : "r"(_ptr) + : "x30"); + return ret; +} + +#define STRIP_PAC(x) (strip_PAC((x))) +#else +#define STRIP_PAC(x) (x) +#endif + struct frame { uintptr_t parent; #ifdef PAD_FRAME @@ -131,7 +152,8 @@ int capture(void **result, int max_depth, int skip_count, if (max_depth == 0) { return 0; } - result[0] = *initial_pc; + result[0] = STRIP_PAC(*initial_pc); + i++; } @@ -189,7 +211,7 @@ int capture(void **result, int max_depth, int skip_count, if (WithSizes) { sizes[i - skip_count] = reinterpret_cast(prev_f) - reinterpret_cast(f); } - result[i - skip_count] = pc; + result[i - skip_count] = STRIP_PAC(pc); } i++;