From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id 0F1923858009 for ; Mon, 25 Apr 2022 14:03:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 0F1923858009 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id A02EBED1; Mon, 25 Apr 2022 07:03:26 -0700 (PDT) Received: from ip-10-252-15-96.eu-west-1.compute.internal (unknown [10.252.15.96]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 087523F774; Mon, 25 Apr 2022 07:03:25 -0700 (PDT) From: German Gomez To: elfutils-devel@sourceware.org Subject: [PATCH 3/4] libdwfl, aarch64: Demangle return addresses using a PAC mask Date: Mon, 25 Apr 2022 14:03:10 +0000 Message-Id: <20220425140311.95231-4-german.gomez@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220425140311.95231-1-german.gomez@arm.com> References: <20220425140311.95231-1-german.gomez@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-13.1 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 25 Apr 2022 14:03:32 -0000 Demangle mangled return addresses on AARCH64. The value of the masks is stored in the struct Dwfl_Thread. Signed-off-by: German Gomez --- libdwfl/dwfl_frame.c | 3 +++ libdwfl/frame_unwind.c | 14 +++++++++++++- libdwfl/libdwflP.h | 7 +++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/libdwfl/dwfl_frame.c b/libdwfl/dwfl_frame.c index 77e0c5cb..88972d8e 100644 --- a/libdwfl/dwfl_frame.c +++ b/libdwfl/dwfl_frame.c @@ -270,6 +270,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, @@ -340,6 +342,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 9ac33833..839d1eff 100644 --- a/libdwfl/frame_unwind.c +++ b/libdwfl/frame_unwind.c @@ -610,7 +610,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 7503a627..d3fe8118 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. */ @@ -782,6 +788,7 @@ INTDECL (dwfl_thread_tid) INTDECL (dwfl_frame_thread) INTDECL (dwfl_thread_state_registers) INTDECL (dwfl_thread_state_register_pc) +INTDECL (dwfl_thread_state_aarch64_pauth) INTDECL (dwfl_getthread_frames) INTDECL (dwfl_getthreads) INTDECL (dwfl_thread_getframes) -- 2.25.1