From patchwork Mon Jun 27 14:49:39 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bhushan Attarde X-Patchwork-Id: 13393 Received: (qmail 11440 invoked by alias); 27 Jun 2016 14:50:46 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 11365 invoked by uid 89); 27 Jun 2016 14:50:46 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=3.7 required=5.0 tests=AWL, BAYES_00, GARBLED_SUBJECT, RCVD_IN_DNSWL_NONE, RP_MATCHES_RCVD, SPF_PASS autolearn=no version=3.3.2 spammy=o32, fallback X-HELO: mailapp01.imgtec.com Received: from mailapp01.imgtec.com (HELO mailapp01.imgtec.com) (195.59.15.196) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 27 Jun 2016 14:50:42 +0000 Received: from hhmail02.hh.imgtec.org (unknown [10.100.10.20]) by Forcepoint Email with ESMTPS id 231892648B967 for ; Mon, 27 Jun 2016 15:50:36 +0100 (IST) Received: from pudesk170.pu.imgtec.org (192.168.93.65) by hhmail02.hh.imgtec.org (10.100.10.20) with Microsoft SMTP Server (TLS) id 14.3.294.0; Mon, 27 Jun 2016 15:50:39 +0100 From: Bhushan Attarde To: CC: , , , , , Bhushan Attarde Subject: [PATCH 12/24] o32 sigframe unwinding with FR1 Date: Mon, 27 Jun 2016 20:19:39 +0530 Message-ID: <1467038991-6600-12-git-send-email-bhushan.attarde@imgtec.com> In-Reply-To: <1467038991-6600-1-git-send-email-bhushan.attarde@imgtec.com> References: <1467038991-6600-1-git-send-email-bhushan.attarde@imgtec.com> MIME-Version: 1.0 gdb/ChangeLog: * mips-linux-tdep.c (SIGCONTEXT_USEDMATH): New definition. (USED_FP, USED_FR1, USED_HYBRID_FPRS): Add fallback definitions. (mips_linux_o32_sigframe_init): Frame override of raw register. --- gdb/mips-linux-tdep.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c index d337a5b..e1f113f 100644 --- a/gdb/mips-linux-tdep.c +++ b/gdb/mips-linux-tdep.c @@ -1053,6 +1053,7 @@ static const struct tramp_frame micromips_linux_n64_rt_sigframe = { #define SIGCONTEXT_REGS (2 * 8) #define SIGCONTEXT_FPREGS (34 * 8) #define SIGCONTEXT_FPCSR (66 * 8 + 4) +#define SIGCONTEXT_USEDMATH (67 * 8 + 4) #define SIGCONTEXT_DSPCTL (68 * 8 + 0) #define SIGCONTEXT_HI (69 * 8) #define SIGCONTEXT_LO (70 * 8) @@ -1067,6 +1068,16 @@ static const struct tramp_frame micromips_linux_n64_rt_sigframe = { #define SIGCONTEXT_REG_SIZE 8 +#ifndef USED_FP +#define USED_FP (1 << 0) +#endif +#ifndef USED_FR1 +#define USED_FR1 (1 << 1) +#endif +#ifndef USED_HYBRID_FPRS +#define USED_HYBRID_FPRS (1 << 2) +#endif + static void mips_linux_o32_sigframe_init (const struct tramp_frame *self, struct frame_info *this_frame, @@ -1079,6 +1090,9 @@ mips_linux_o32_sigframe_init (const struct tramp_frame *self, CORE_ADDR sigcontext_base; const struct mips_regnum *regs = mips_regnum (gdbarch); CORE_ADDR regs_base; + gdb_byte buf[4]; + uint32_t used_math; + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); if (self == &mips_linux_o32_sigframe || self == µmips_linux_o32_sigframe) @@ -1109,6 +1123,14 @@ mips_linux_o32_sigframe_init (const struct tramp_frame *self, (regs_base + SIGCONTEXT_REGS + ireg * SIGCONTEXT_REG_SIZE)); + /* Read the used_math field. */ + if (safe_frame_unwind_memory (this_frame, + sigcontext_base + SIGCONTEXT_USEDMATH, + buf, 4)) + used_math = extract_unsigned_integer (buf, 4, gdbarch_byte_order (gdbarch)); + else + used_math = 0; + /* The way that floating point registers are saved, unfortunately, depends on the architecture the kernel is built for. For the r3000 and tx39, four bytes of each register are at the beginning of each of the @@ -1118,7 +1140,18 @@ mips_linux_o32_sigframe_init (const struct tramp_frame *self, layout, since we can't tell, and it's much more common. Which bits are the "high" bits depends on endianness. */ for (ireg = 0; ireg < 32; ireg++) - if ((gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) != (ireg & 1)) + if (used_math & USED_FR1) + { + trad_frame_set_reg_addr (this_cache, + ireg + regs->fp0, + (sigcontext_base + SIGCONTEXT_FPREGS + + ireg * SIGCONTEXT_REG_SIZE)); + trad_frame_set_reg_addr (this_cache, + ireg + regs->fp0 + gdbarch_num_regs (gdbarch), + (sigcontext_base + SIGCONTEXT_FPREGS + + ireg * SIGCONTEXT_REG_SIZE)); + } + else if ((gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) != (ireg & 1)) trad_frame_set_reg_addr (this_cache, ireg + regs->fp0 + gdbarch_num_regs (gdbarch), (sigcontext_base + SIGCONTEXT_FPREGS + 4