From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx07-00178001.pphosted.com (mx07-00178001.pphosted.com [185.132.182.106]) by sourceware.org (Postfix) with ESMTPS id 6C2443858016 for ; Mon, 10 Oct 2022 18:10:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 6C2443858016 Received: from pps.filterd (m0241204.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 29AGhCZ4018181; Mon, 10 Oct 2022 20:10:43 +0200 Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 3k31m9cnr9-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 10 Oct 2022 20:10:43 +0200 Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 7969A10002A; Mon, 10 Oct 2022 20:10:38 +0200 (CEST) Received: from Webmail-eu.st.com (shfdag1node3.st.com [10.75.129.71]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 52F4924B8B8; Mon, 10 Oct 2022 20:10:38 +0200 (CEST) Received: from jkgcxl0002.jkg.st.com (10.75.127.120) by SHFDAG1NODE3.st.com (10.75.129.71) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) id 15.1.2375.31; Mon, 10 Oct 2022 20:10:35 +0200 From: =?UTF-8?q?Torbj=C3=B6rn=20SVENSSON?= To: Subject: [PATCH] gdb/arm: Properly unwind S-registers for exception frames Date: Mon, 10 Oct 2022 20:09:47 +0200 Message-ID: <20221010180946.528256-1-torbjorn.svensson@foss.st.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8bit X-Originating-IP: [10.75.127.120] X-ClientProxiedBy: GPXDAG2NODE4.st.com (10.75.127.68) To SHFDAG1NODE3.st.com (10.75.129.71) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.528,FMLib:17.11.122.1 definitions=2022-10-10_12,2022-10-10_02,2022-06-22_01 X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP 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: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2022 18:10:47 -0000 For each D-register, there are 2 S-registers. In the GDB architecture, the S-registers are implemented as pseudo registers. As the value for the S-registers can be stacked, the value needs to be extracted from the corresponding D-register and returned in the associated prev_register function. Signed-off-by: Torbjörn SVENSSON --- gdb/arm-tdep.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index d357066653b..7168e2a5edc 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -261,6 +261,8 @@ static void arm_neon_quad_write (struct gdbarch *gdbarch, static CORE_ADDR arm_get_next_pcs_syscall_next_pc (struct arm_get_next_pcs *self); +static bool is_s_pseudo (struct gdbarch *gdbarch, int regnum); + /* get_next_pcs operations. */ static struct arm_get_next_pcs_ops arm_get_next_pcs_ops = { @@ -3726,8 +3728,8 @@ arm_m_exception_prev_register (struct frame_info *this_frame, cache = (struct arm_prologue_cache *) *this_cache; /* The value was already reconstructed into PREV_SP. */ - arm_gdbarch_tdep *tdep - = gdbarch_tdep (get_frame_arch (this_frame)); + struct gdbarch *gdbarch = get_frame_arch (this_frame); + arm_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); if (prev_regnum == ARM_SP_REGNUM) return frame_unwind_got_constant (this_frame, prev_regnum, arm_cache_get_prev_sp_value (cache, tdep)); @@ -3756,7 +3758,6 @@ arm_m_exception_prev_register (struct frame_info *this_frame, pattern. */ if (prev_regnum == ARM_PS_REGNUM) { - struct gdbarch *gdbarch = get_frame_arch (this_frame); struct value *value = trad_frame_get_prev_register (this_frame, cache->saved_regs, ARM_PC_REGNUM); @@ -3770,6 +3771,30 @@ arm_m_exception_prev_register (struct frame_info *this_frame, return frame_unwind_got_constant (this_frame, ARM_PS_REGNUM, xpsr); } + /* If we are asked to unwind Sn, unwind Dm where m is n/2 and take the + corresponding part of the D register. */ + if (is_s_pseudo (gdbarch, prev_regnum)) + { + int single_regnum = prev_regnum - tdep->s_pseudo_base; + int double_regnum = ARM_D0_REGNUM + single_regnum / 2; + int offset; + + struct value *value = trad_frame_get_prev_register (this_frame, + cache->saved_regs, + double_regnum); + + gdb::array_view raw = value_contents (value); + + /* s0 is always the least significant half of d0. */ + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + offset = (single_regnum & 1) ? 0 : 4; + else + offset = (single_regnum & 1) ? 4 : 0; + + return frame_unwind_got_bytes (this_frame, prev_regnum, + raw.slice (offset).data ()); + } + return trad_frame_get_prev_register (this_frame, cache->saved_regs, prev_regnum); } -- 2.25.1