From: German Gomez <german.go...@arm.com> Demangle mangled return addresses on AARCH64. The value of the masks is stored in the struct Dwfl_Thread.
Signed-off-by: German Gomez <german.go...@arm.com> [SteveC: remove dwfl_thread_state_aarch64_pauth] Signed-off-by: Steve Capper <steve.cap...@arm.com> --- libdwfl/dwfl_frame.c | 3 +++ libdwfl/frame_unwind.c | 14 +++++++++++++- libdwfl/libdwflP.h | 6 ++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/libdwfl/dwfl_frame.c b/libdwfl/dwfl_frame.c index 5ee71dd4..8af8843f 100644 --- a/libdwfl/dwfl_frame.c +++ b/libdwfl/dwfl_frame.c @@ -269,6 +269,8 @@ dwfl_getthreads (Dwfl *dwfl, int (*callback) (Dwfl_Thread *thread, void *arg), thread.process = process; thread.unwound = NULL; thread.callbacks_arg = NULL; + thread.aarch64.pauth_insn_mask = 0; + for (;;) { thread.tid = process->callbacks->next_thread (dwfl, @@ -339,6 +341,7 @@ getthread (Dwfl *dwfl, pid_t tid, thread.process = process; thread.unwound = NULL; thread.callbacks_arg = NULL; + thread.aarch64.pauth_insn_mask = 0; if (process->callbacks->get_thread (dwfl, tid, process->callbacks_arg, &thread.callbacks_arg)) diff --git a/libdwfl/frame_unwind.c b/libdwfl/frame_unwind.c index 1e2f0255..ab444d25 100644 --- a/libdwfl/frame_unwind.c +++ b/libdwfl/frame_unwind.c @@ -599,7 +599,19 @@ handle_cfi (Dwfl_Frame *state, Dwarf_Addr pc, Dwarf_CFI *cfi, Dwarf_Addr bias) /* Some architectures encode some extra info in the return address. */ if (regno == frame->fde->cie->return_address_register) - regval &= ebl_func_addr_mask (ebl); + { + regval &= ebl_func_addr_mask (ebl); + + /* In aarch64, pseudo-register RA_SIGN_STATE indicates whether the + return address needs demangling using the PAC mask from the + thread. */ + if (cfi->e_machine == EM_AARCH64 && + frame->nregs > DW_AARCH64_RA_SIGN_STATE && + frame->regs[DW_AARCH64_RA_SIGN_STATE].value & 0x1) + { + regval &= ~(state->thread->aarch64.pauth_insn_mask); + } + } /* This is another strange PPC[64] case. There are two registers numbers that can represent the same DWARF return diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h index e0055d65..d0a5f056 100644 --- a/libdwfl/libdwflP.h +++ b/libdwfl/libdwflP.h @@ -244,6 +244,12 @@ struct Dwfl_Thread /* Bottom (innermost) frame while we're initializing, NULL afterwards. */ Dwfl_Frame *unwound; void *callbacks_arg; + + /* Data for handling AARCH64 (currently limited to demangling PAC from + return addresses). */ + struct { + Dwarf_Addr pauth_insn_mask; + } aarch64; }; /* See its typedef in libdwfl.h. */ -- 2.43.0