From patchwork Mon Aug 26 10:52:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Capper X-Patchwork-Id: 96486 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E106A385EC13 for ; Mon, 26 Aug 2024 10:53:31 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id BBBFD3858403 for ; Mon, 26 Aug 2024 10:53:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org BBBFD3858403 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org BBBFD3858403 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1724669598; cv=none; b=Ucj/wEtoJK2VVn29PE3YxngkoPgHlktLm4+CsVY+JDJV0u/HUs7XIhnXhcaTq3aCtHz5UfLslt741TYo2uWIWBuBQfQ4vgO15ZfKlsCFk/PK0yTn53gryZx255jXKoCPkiKyJoNRsc2p59kBh0kUEvdsdB4K7GXh6+NsU6mnftI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1724669598; c=relaxed/simple; bh=PpqRiIeh4alGC+vptX8X6hWx9f3gFawDHxPpQRTTB6A=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=QdZoonEfDx6O8sUWR6vBIYSf1B8+MFA1fuYgOj+IjlPbQRYYEpNXDa+dANfBF5H+Lv/PSfzgMb92nUqS8D3Cx+o0KNaqIM+kFi42HEbQpmtNW99bS8NO1jBgP6zBxb+XdCH7EczmlMhu0+qlwh6+KuW1s04AeILKG0tN/faSa4A= ARC-Authentication-Results: i=1; server2.sourceware.org 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 B90D611FB; Mon, 26 Aug 2024 03:53:41 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id CF3B33F66E; Mon, 26 Aug 2024 03:53:14 -0700 (PDT) From: Steve Capper To: elfutils-devel@sourceware.org Cc: mark@klomp.org, german.gomez@arm.com, ema@debian.org, Steve Capper Subject: [PATCH v2 1/5] aarch64: Create definitions for AARCH64_RA_SIGN_STATE register Date: Mon, 26 Aug 2024 11:52:53 +0100 Message-ID: <20240826105257.2669-2-steve.capper@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240826105257.2669-1-steve.capper@arm.com> References: <20240826105257.2669-1-steve.capper@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces~patchwork=sourceware.org@sourceware.org From: German Gomez This register will be used to indicate whether a return address is mangled with a PAC or not, in accordance with the DWARF AARCH64 ABI [1]. [1] https://github.com/ARM-software/abi-aa/blob/main/aadwarf64/aadwarf64.rst#41dwarf-register-names Signed-off-by: German Gomez [SteveC: move DW_AARCH64_RA_SIGN_STATE to cfi.h, fix comments] Signed-off-by: Steve Capper --- backends/aarch64_initreg.c | 2 ++ backends/aarch64_regs.c | 5 ++++- libdw/cfi.h | 5 +++++ tests/run-addrcfi.sh | 1 + tests/run-allregs.sh | 1 + 5 files changed, 13 insertions(+), 1 deletion(-) diff --git a/backends/aarch64_initreg.c b/backends/aarch64_initreg.c index daf6f375..4661068a 100644 --- a/backends/aarch64_initreg.c +++ b/backends/aarch64_initreg.c @@ -73,6 +73,8 @@ aarch64_set_initial_registers_tid (pid_t tid __attribute__ ((unused)), /* ELR cannot be found. */ + /* RA_SIGN_STATE cannot be found */ + /* FP registers (only 64bits are used). */ struct user_fpsimd_struct fregs; iovec.iov_base = &fregs; diff --git a/backends/aarch64_regs.c b/backends/aarch64_regs.c index 23014bfc..e95ece37 100644 --- a/backends/aarch64_regs.c +++ b/backends/aarch64_regs.c @@ -87,7 +87,10 @@ aarch64_register_info (Ebl *ebl __attribute__ ((unused)), case 33: return regtype ("integer", DW_ATE_address, "elr"); - case 34 ... 63: + case 34: + return regtype ("integer", DW_ATE_unsigned, "ra_sign_state"); + + case 35 ... 63: return 0; case 64 ... 95: diff --git a/libdw/cfi.h b/libdw/cfi.h index bb9dc0df..d0134243 100644 --- a/libdw/cfi.h +++ b/libdw/cfi.h @@ -228,6 +228,11 @@ extern int __libdw_frame_at_address (Dwarf_CFI *cache, struct dwarf_fde *fde, { ((BYTE_ORDER == LITTLE_ENDIAN && e_ident[EI_DATA] == ELFDATA2MSB) \ || (BYTE_ORDER == BIG_ENDIAN && e_ident[EI_DATA] == ELFDATA2LSB)) } +/* AARCH64 DWARF registers. */ +enum + { + DW_AARCH64_RA_SIGN_STATE = 34 + }; INTDECL (dwarf_next_cfi) INTDECL (dwarf_getcfi) diff --git a/tests/run-addrcfi.sh b/tests/run-addrcfi.sh index 64fa24d7..ce9e753e 100755 --- a/tests/run-addrcfi.sh +++ b/tests/run-addrcfi.sh @@ -3639,6 +3639,7 @@ dwarf_cfi_addrframe (.eh_frame): no matching address range integer reg30 (x30): same_value integer reg31 (sp): location expression: call_frame_cfa stack_value integer reg33 (elr): undefined + integer reg34 (ra_sign_state): undefined FP/SIMD reg64 (v0): undefined FP/SIMD reg65 (v1): undefined FP/SIMD reg66 (v2): undefined diff --git a/tests/run-allregs.sh b/tests/run-allregs.sh index 87b16c95..ed086651 100755 --- a/tests/run-allregs.sh +++ b/tests/run-allregs.sh @@ -2693,6 +2693,7 @@ integer registers: 30: x30 (x30), signed 64 bits 31: sp (sp), address 64 bits 33: elr (elr), address 64 bits + 34: ra_sign_state (ra_sign_state), unsigned 64 bits FP/SIMD registers: 64: v0 (v0), unsigned 128 bits 65: v1 (v1), unsigned 128 bits From patchwork Mon Aug 26 10:52:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Capper X-Patchwork-Id: 96487 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4D550385C6C6 for ; Mon, 26 Aug 2024 10:53:33 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id 2F5D63857349 for ; Mon, 26 Aug 2024 10:53:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2F5D63857349 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 2F5D63857349 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1724669600; cv=none; b=EQt5aHP97h8EjzdsOU3Tw2DM4++rE3TYXW1Qv/Zx+EbAn9y+tFPbyNxtfXko7ziXpkQa905pkXEN+l/YaFqnmrpSHnSzEP+usvI+EGXTt1iaX4lyws3pZroWIVeit1MyeCC8ulg2Q0AajftlOXNJmYM97ZGW/aQGJRR88a19PM0= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1724669600; c=relaxed/simple; bh=XZZaANhsP4ky1DJlx6qYB6IAo37++dBN1efiqbehweg=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=IdhRf6SDaTfPD7NmAU82MiOgl1yfAJhg/7q/RboZ11uX+lunr1SX+QH+9XFlOJ3Fb8alI8O/3Noy4pNNazKInjxk6sDccFKatNxHjXrs9Blf9GZDtVBgyI987SwZrlamK/8U8wJ1KojHYJS15eirc0ngaKVVl+xxpQZ+hz+Lqy4= ARC-Authentication-Results: i=1; server2.sourceware.org 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 2AC2512FC; Mon, 26 Aug 2024 03:53:45 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 4B6BF3F66E; Mon, 26 Aug 2024 03:53:18 -0700 (PDT) From: Steve Capper To: elfutils-devel@sourceware.org Cc: mark@klomp.org, german.gomez@arm.com, ema@debian.org, Steve Capper Subject: [PATCH v2 2/5] libdw, aarch64: Implement DW_CFA_AARCH64_negate_ra_state CFI instruction Date: Mon, 26 Aug 2024 11:52:54 +0100 Message-ID: <20240826105257.2669-3-steve.capper@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240826105257.2669-1-steve.capper@arm.com> References: <20240826105257.2669-1-steve.capper@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces~patchwork=sourceware.org@sourceware.org From: German Gomez Implement DW_CFA_AARCH64_negate_ra_state in accordance with the DWARF AARCH64 ABI [1]. Followup commits will use the value of this register to remove the PAC from return addresses. [1] https://github.com/ARM-software/abi-aa/blob/main/aadwarf64/aadwarf64.rst#44call-frame-instructions Signed-off-by: German Gomez Signed-off-by: Steve Capper --- libdw/cfi.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/libdw/cfi.c b/libdw/cfi.c index a7174405..743bfc07 100644 --- a/libdw/cfi.c +++ b/libdw/cfi.c @@ -125,6 +125,15 @@ execute_cfi (Dwarf_CFI *cache, fs->regs[regno].value = (r_value); \ } while (0) + /* The AARCH64 DWARF ABI states that register 34 (ra_sign_state) must + be initialized to 0. So do it before executing the CFI. */ + if (cache->e_machine == EM_AARCH64) + { + if (unlikely (! enough_registers (DW_AARCH64_RA_SIGN_STATE, &fs, &result))) + goto out; + fs->regs[DW_AARCH64_RA_SIGN_STATE].value = 0; + } + while (program < end) { uint8_t opcode = *program++; @@ -357,7 +366,10 @@ execute_cfi (Dwarf_CFI *cache, { /* Toggles the return address state, indicating whether the return address is encrypted or not on - aarch64. XXX not handled yet. */ + aarch64. */ + if (unlikely (! enough_registers (DW_AARCH64_RA_SIGN_STATE, &fs, &result))) + goto out; + fs->regs[DW_AARCH64_RA_SIGN_STATE].value ^= 0x1; } else { From patchwork Mon Aug 26 10:52:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Capper X-Patchwork-Id: 96488 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 818FD385EC13 for ; Mon, 26 Aug 2024 10:53:36 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id 781F83858C3A for ; Mon, 26 Aug 2024 10:53:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 781F83858C3A Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 781F83858C3A Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1724669604; cv=none; b=dTHWfppgs3PjZ/qS9w0/ZrRIWopPYj48mZoFsyw+3ebVghUqTAAs0ktRHStYLwbDLMnwqoBnLKlDhhGT4vxu1f5wIZxYL8/fdjjSYK+CsZ1oWMAIOJswGsa5yyumEIB622YioMfWDU2lgBZBpsiGxG2dDq2QKxJMbXvXyJjUFOE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1724669604; c=relaxed/simple; bh=MMFeZj1/0XnDO1m2fwuTuVUJ+2Q5JlyyHwAY2BUC4yI=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=DRFnDQNHSTiMo0Yog7+QSDYa7DsOXhiyX/1t5+LY6+EmgJzIvmGDfhQS7qpO2k2ONizOGyg576j9rG+csJ7swEuRB6YTKnI8t0Kmz+wlpWcVlbtIMeAv/a8sbruF8XUzCn//qkuAKuBzh901NcgMlHXpqghy+mk5L5vGtjQ3RRY= ARC-Authentication-Results: i=1; server2.sourceware.org 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 752ED139F; Mon, 26 Aug 2024 03:53:48 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 96DD73F66E; Mon, 26 Aug 2024 03:53:21 -0700 (PDT) From: Steve Capper To: elfutils-devel@sourceware.org Cc: mark@klomp.org, german.gomez@arm.com, ema@debian.org, Steve Capper Subject: [PATCH v2 3/5] libdwfl, aarch64: Demangle return addresses using a PAC mask Date: Mon, 26 Aug 2024 11:52:55 +0100 Message-ID: <20240826105257.2669-4-steve.capper@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240826105257.2669-1-steve.capper@arm.com> References: <20240826105257.2669-1-steve.capper@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces~patchwork=sourceware.org@sourceware.org From: German Gomez Demangle mangled return addresses on AARCH64. The value of the masks is stored in the struct Dwfl_Thread. Signed-off-by: German Gomez [SteveC: remove dwfl_thread_state_aarch64_pauth] Signed-off-by: Steve Capper --- 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. */ From patchwork Mon Aug 26 10:52:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Capper X-Patchwork-Id: 96490 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 56B61385EC3E for ; Mon, 26 Aug 2024 10:53:52 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id 3DF893857C4F for ; Mon, 26 Aug 2024 10:53:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 3DF893857C4F Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 3DF893857C4F Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1724669607; cv=none; b=cyQf3vFqf8wFdk7pBqrLpcdEWTENoKDrM2pa9F3lYkQNFmCJP7XwSN7HhMna0kgPt8aO0nHxoL5AN8uienpFquMApiRebq+swdDrbymGtaFJ/hqO0aQic02nMy3JHbH+PWfb4Bbepb+M71qFmEGeQcytbID4OtnfGJV0k8unhm4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1724669607; c=relaxed/simple; bh=svl0eZck+X/gNlQkjiYQknBepcfYYw8d07vIyVx1O2Y=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=T6dUW3hOWTt5ez4c75tfmXd9mzBj2jx/CIxDh22Xv6EtfYpVjtTTFOeov8UztdqSKB31H1Ac3Pu6hVNHnAVCwMe1AFV1+IIGFX31a8qLWL8ZEANx4NT4OmLXwi05g2LbLw5pU3FCx+L29Kux7GKC+1vwI/4jW8TCalmRhptiAPs= ARC-Authentication-Results: i=1; server2.sourceware.org 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 1D43313D5; Mon, 26 Aug 2024 03:53:51 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 3C68C3F66E; Mon, 26 Aug 2024 03:53:24 -0700 (PDT) From: Steve Capper To: elfutils-devel@sourceware.org Cc: mark@klomp.org, german.gomez@arm.com, ema@debian.org, Steve Capper Subject: [PATCH v2 4/5] libdwfl, aarch64: extend dwfl_thread_state_registers to handle PAC Date: Mon, 26 Aug 2024 11:52:56 +0100 Message-ID: <20240826105257.2669-5-steve.capper@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240826105257.2669-1-steve.capper@arm.com> References: <20240826105257.2669-1-steve.capper@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces~patchwork=sourceware.org@sourceware.org On AArch64 systems with pointer authentication enabled, one needs to know the PAC mask in order to unwind functions that employ PAC. This patch extends dwfl_thread_state_registers to handle the PAC mask information by introducing a special register -2. (-1 is used in a similar manner already for handling the program counter). The AArch64 linux process attach logic is also extended to query ptrace for the PAC mask. A subsequent patch will add support for retrieving the PAC mask from an AArch64 linux core file. Signed-off-by: Steve Capper --- backends/aarch64_initreg.c | 10 ++++++++++ libdwfl/dwfl_frame_regs.c | 6 ++++++ libdwfl/linux-pid-attach.c | 9 +++++++-- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/backends/aarch64_initreg.c b/backends/aarch64_initreg.c index 4661068a..5ec45ea6 100644 --- a/backends/aarch64_initreg.c +++ b/backends/aarch64_initreg.c @@ -36,6 +36,7 @@ # include # include # include +# include /* Deal with old glibc defining user_pt_regs instead of user_regs_struct. */ # ifndef HAVE_SYS_USER_REGS # define user_regs_struct user_pt_regs @@ -57,12 +58,18 @@ aarch64_set_initial_registers_tid (pid_t tid __attribute__ ((unused)), /* General registers. */ struct user_regs_struct gregs; + struct user_pac_mask pac_mask; struct iovec iovec; iovec.iov_base = &gregs; iovec.iov_len = sizeof (gregs); if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iovec) != 0) return false; + iovec.iov_base = &pac_mask; + iovec.iov_len = sizeof (pac_mask); + if (ptrace (PTRACE_GETREGSET, tid, NT_ARM_PAC_MASK, &iovec) != 0) + pac_mask.insn_mask = 0; + /* X0..X30 plus SP. */ if (! setfunc (0, 32, (Dwarf_Word *) &gregs.regs[0], arg)) return false; @@ -71,6 +78,9 @@ aarch64_set_initial_registers_tid (pid_t tid __attribute__ ((unused)), if (! setfunc (-1, 1, (Dwarf_Word *) &gregs.pc, arg)) return false; + if (! setfunc (-2, 1, (Dwarf_Word *) &pac_mask.insn_mask, arg)) + return false; + /* ELR cannot be found. */ /* RA_SIGN_STATE cannot be found */ diff --git a/libdwfl/dwfl_frame_regs.c b/libdwfl/dwfl_frame_regs.c index a4bd3884..572ac676 100644 --- a/libdwfl/dwfl_frame_regs.c +++ b/libdwfl/dwfl_frame_regs.c @@ -39,6 +39,12 @@ dwfl_thread_state_registers (Dwfl_Thread *thread, int firstreg, Dwfl_Frame *state = thread->unwound; assert (state && state->unwound == NULL); assert (state->initial_frame); + + if (firstreg == -2 && nregs == 1) { + thread->aarch64.pauth_insn_mask = regs[0]; + return true; + } + for (unsigned regno = firstreg; regno < firstreg + nregs; regno++) if (! __libdwfl_frame_reg_set (state, regno, regs[regno - firstreg])) { diff --git a/libdwfl/linux-pid-attach.c b/libdwfl/linux-pid-attach.c index de867857..0eec1e88 100644 --- a/libdwfl/linux-pid-attach.c +++ b/libdwfl/linux-pid-attach.c @@ -309,13 +309,18 @@ pid_thread_state_registers_cb (int firstreg, unsigned nregs, const Dwarf_Word *regs, void *arg) { Dwfl_Thread *thread = (Dwfl_Thread *) arg; - if (firstreg < 0) + if (firstreg == -1) { - assert (firstreg == -1); assert (nregs == 1); INTUSE(dwfl_thread_state_register_pc) (thread, *regs); return true; } + else if (firstreg == -2) + { + assert (nregs == 1); + INTUSE(dwfl_thread_state_registers) (thread, firstreg, nregs, regs); + return true; + } assert (nregs > 0); return INTUSE(dwfl_thread_state_registers) (thread, firstreg, nregs, regs); } From patchwork Mon Aug 26 10:52:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Capper X-Patchwork-Id: 96489 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5C68F3858403 for ; Mon, 26 Aug 2024 10:53:50 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id 9D1D8385EC20 for ; Mon, 26 Aug 2024 10:53:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9D1D8385EC20 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 9D1D8385EC20 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1724669611; cv=none; b=uRzajuzBEeirhlQhDfu8ytN5lsHjm3lDabjlM6suzzvDdCeHyyCz7dDF7y6ZGMi9PiprTNfELuhL+GsA/ywEMM0SKx876oELNeHDnNCJTZxjvEgxUDkAPYcwwAeBASJCKHq7wCFQ5LBd9MfbF8rwtll1I7ezL1jy6rNtRcpPdx8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1724669611; c=relaxed/simple; bh=b+qT+ZqnLc3oQOduOlrfIzw7bhxyJIrZv9RyGlzyq/I=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=TVV0T3aprPFiB+jNrILIYZxxCnAp6p2g8eFvfz0VUum4VBBKLmdRpfbuksPPOY6k3uqisnxK4T09mgWuHxlWRdOBBRFW/XQfkl19cErtBgUu1i7h7uT/3h39N61Ly5vAMxTzHbtz5sb26L06XRCx4yWYJvhvEvrk9IT/xCBibc8= ARC-Authentication-Results: i=1; server2.sourceware.org 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 976F31424; Mon, 26 Aug 2024 03:53:53 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id B64EB3F66E; Mon, 26 Aug 2024 03:53:26 -0700 (PDT) From: Steve Capper To: elfutils-devel@sourceware.org Cc: mark@klomp.org, german.gomez@arm.com, ema@debian.org, Steve Capper Subject: [PATCH v2 5/5] libdwfl, aarch64: Read PAC mask from core Date: Mon, 26 Aug 2024 11:52:57 +0100 Message-ID: <20240826105257.2669-6-steve.capper@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240826105257.2669-1-steve.capper@arm.com> References: <20240826105257.2669-1-steve.capper@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces~patchwork=sourceware.org@sourceware.org We need to read the PAC mask from a core file when debugging offline as the information is still needed to demangle return addresses. This commit pulls out the NT_ARM_PAC_MASK info from the core and feeds it through to dwfl_thread_state_registers for each thread. Signed-off-by: Steve Capper --- backends/aarch64_corenote.c | 17 +++++++++++++++-- libdwfl/linux-core-attach.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/backends/aarch64_corenote.c b/backends/aarch64_corenote.c index bd0a4a72..38b21de7 100644 --- a/backends/aarch64_corenote.c +++ b/backends/aarch64_corenote.c @@ -115,6 +115,18 @@ static const Ebl_Core_Item aarch64_mte_items [] = } }; +static const Ebl_Core_Item aarch64_pac_items [] = + { + { + .name = "data_mask", .type = ELF_T_XWORD, .format = 'x', + .offset = 0, .group = "register" + }, + { + .name = "insn_mask", .type = ELF_T_XWORD, .format = 'x', + .offset = 8, .group = "register" + } + }; + #define AARCH64_HWBP_REG(KIND, N) \ { \ .name = "DBG" KIND "VR" #N "_EL1", .type = ELF_T_XWORD, .format = 'x', \ @@ -175,7 +187,8 @@ AARCH64_BP_WP_GROUP ("W", aarch64_hw_wp_items); EXTRA_ITEMS (NT_ARM_TLS, 8, aarch64_tls_items) \ EXTRA_ITEMS (NT_ARM_HW_BREAK, 264, aarch64_hw_bp_items) \ EXTRA_ITEMS (NT_ARM_HW_WATCH, 264, aarch64_hw_wp_items) \ - EXTRA_ITEMS (NT_ARM_SYSTEM_CALL, 4, aarch64_syscall_items) \ - EXTRA_ITEMS (NT_ARM_TAGGED_ADDR_CTRL, 8, aarch64_mte_items) + EXTRA_ITEMS (NT_ARM_SYSTEM_CALL, 4, aarch64_syscall_items) \ + EXTRA_ITEMS (NT_ARM_TAGGED_ADDR_CTRL, 8, aarch64_mte_items) \ + EXTRA_ITEMS (NT_ARM_PAC_MASK, 16, aarch64_pac_items) #include "linux-core-note.c" diff --git a/libdwfl/linux-core-attach.c b/libdwfl/linux-core-attach.c index d6f9e971..75e3c219 100644 --- a/libdwfl/linux-core-attach.c +++ b/libdwfl/linux-core-attach.c @@ -289,6 +289,40 @@ core_set_initial_registers (Dwfl_Thread *thread, void *thread_arg_voidp) reg_desc += regloc->pad; } } + + /* look for any Pointer Authentication code masks on AArch64 machines */ + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = gelf_getehdr(core, &ehdr_mem); + if (ehdr && ehdr->e_machine == EM_AARCH64) + { + while (offset < note_data->d_size + && (offset = gelf_getnote (note_data, offset, + &nhdr, &name_offset, &desc_offset)) > 0) + { + if (nhdr.n_type != NT_ARM_PAC_MASK) + continue; + + name = (nhdr.n_namesz == 0 ? "" : note_data->d_buf + name_offset); + desc = note_data->d_buf + desc_offset; + core_note_err = ebl_core_note (core_arg->ebl, &nhdr, name, desc, + ®s_offset, &nregloc, ®locs, + &nitems, &items); + if (!core_note_err) + break; + + for (item = items; item < items + nitems; item++) + if (strcmp(item->name, "insn_mask") == 0) + break; + + if (item == items + nitems) + continue; + + uint64_t insn_mask = read_8ubyte_unaligned_noncvt(desc + item->offset); + INTUSE(dwfl_thread_state_registers)(thread, -2, 1, &insn_mask); + break; + } + } + return true; }