Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Jim Wilson <jimw@sifive.com>
To: gdb-patches@sourceware.org
Cc: Jim Wilson <jimw@sifive.com>
Subject: [PATCH 2/2] RISC-V: Linux signal frame support.
Date: Fri, 26 Oct 2018 00:01:00 -0000	[thread overview]
Message-ID: <20181026000030.3847-1-jimw@sifive.com> (raw)
In-Reply-To: <CAFyWVaYFSWGfC_idDngHGd6fMKO8n2hohzdXWXcBh0MoqCqfTA@mail.gmail.com>

Add support for recognizing signal trampolines, parsing the signal frame,
and reading register values from it.

	gdb/
	* riscv-linux-tdep.c: Include tramp-frame.h and trad-frame.h.
	(riscv_linux_sigframe_init): Declare.
	(RISCV_INST_LI_A7_SIGRETURN, RISCV_INT_ECALL): New.
	(riscv_linux_sigframe): New.
	(SIGFRAME_SIGINFO_SIZE, UCONTEXT_MCONTEXT_OFFSET): New.
	(riscv_linux_sigframe_init): Define.
	(riscv_linux_init_abi): Call tramp_frame_prepend_unwinder.
---
 gdb/riscv-linux-tdep.c | 80 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 80 insertions(+)

diff --git a/gdb/riscv-linux-tdep.c b/gdb/riscv-linux-tdep.c
index d072c0b754..ece75dba47 100644
--- a/gdb/riscv-linux-tdep.c
+++ b/gdb/riscv-linux-tdep.c
@@ -23,6 +23,8 @@
 #include "linux-tdep.h"
 #include "solib-svr4.h"
 #include "regset.h"
+#include "tramp-frame.h"
+#include "trad-frame.h"
 
 /* Define the general register mapping.  The kernel puts the PC at offset 0,
    gdb puts it at offset 32.  Register x0 is always 0 and can be ignored.
@@ -56,6 +58,82 @@ riscv_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
   /* TODO: Add FP register support.  */
 }
 
+/* Signal trampoline support.  */
+
+static void riscv_linux_sigframe_init (const struct tramp_frame *self,
+				       struct frame_info *this_frame,
+				       struct trad_frame_cache *this_cache,
+				       CORE_ADDR func);
+
+#define RISCV_INST_LI_A7_SIGRETURN	0x08b00893
+#define RISCV_INST_ECALL		0x00000073
+
+static const struct tramp_frame riscv_linux_sigframe = {
+  SIGTRAMP_FRAME,
+  4,
+  {
+    { RISCV_INST_LI_A7_SIGRETURN, ULONGEST_MAX },
+    { RISCV_INST_ECALL, ULONGEST_MAX },
+    { TRAMP_SENTINEL_INSN }
+  },
+  riscv_linux_sigframe_init,
+  NULL
+};
+
+/* Runtime signal frames look like this:
+   struct rt_sigframe {
+     struct siginfo info;
+     struct ucontext uc;
+   };
+
+   struct ucontext {
+     unsigned long __uc_flags;
+     struct ucontext *uclink;
+     stack_t uc_stack;
+     sigset_t uc_sigmask;
+     char __glibc_reserved[1024 / 8 - sizeof (sigset_t)];
+     mcontext_t uc_mcontext;
+   }; */
+
+#define SIGFRAME_SIGINFO_SIZE		128
+#define UCONTEXT_MCONTEXT_OFFSET	176
+
+static void
+riscv_linux_sigframe_init (const struct tramp_frame *self,
+			   struct frame_info *this_frame,
+			   struct trad_frame_cache *this_cache,
+			   CORE_ADDR func)
+{
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  int xlen = riscv_isa_xlen (gdbarch);
+  int flen = riscv_isa_flen (gdbarch);
+  CORE_ADDR frame_sp = get_frame_sp (this_frame);
+  CORE_ADDR mcontext_base;
+  CORE_ADDR regs_base;
+
+  mcontext_base = frame_sp + SIGFRAME_SIGINFO_SIZE + UCONTEXT_MCONTEXT_OFFSET;
+
+  /* Handle the integer registers.  The first one is PC, followed by x1
+     through x31.  */
+  regs_base = mcontext_base;
+  trad_frame_set_reg_addr (this_cache, RISCV_PC_REGNUM, regs_base);
+  for (int i = 1; i < 32; i++)
+    trad_frame_set_reg_addr (this_cache, RISCV_ZERO_REGNUM + i,
+			     regs_base + (i * xlen));
+
+  /* Handle the FP registers.  First comes the 32 FP registers, followed by
+     fcsr.  */
+  regs_base += 32 * xlen;
+  for (int i = 0; i < 32; i++)
+    trad_frame_set_reg_addr (this_cache, RISCV_FIRST_FP_REGNUM + i,
+			     regs_base + (i * flen));
+  regs_base += 32 * flen;
+  trad_frame_set_reg_addr (this_cache, RISCV_CSR_FCSR_REGNUM, regs_base);
+
+  /* Choice of the bottom of the sigframe is somewhat arbitrary.  */
+  trad_frame_set_id (this_cache, frame_id_build (frame_sp, func));
+}
+
 /* Initialize RISC-V Linux ABI info.  */
 
 static void
@@ -82,6 +160,8 @@ riscv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   set_gdbarch_iterate_over_regset_sections
     (gdbarch, riscv_linux_iterate_over_regset_sections);
+
+  tramp_frame_prepend_unwinder (gdbarch, &riscv_linux_sigframe);
 }
 
 /* Initialize RISC-V Linux target support.  */
-- 
2.17.1


  parent reply	other threads:[~2018-10-26  0:01 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-25 23:59 [PATCH 0/2] " Jim Wilson
2018-10-25 23:59 ` [PATCH 1/2] " Jim Wilson
2018-10-26  3:25   ` Kevin Buettner
2018-10-26 17:34     ` Jim Wilson
2018-10-26  0:01 ` Jim Wilson [this message]
2018-10-26  3:58   ` [PATCH 2/2] " Kevin Buettner
2018-10-26  7:32 ` [PATCH 0/2] " Andrew Burgess

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181026000030.3847-1-jimw@sifive.com \
    --to=jimw@sifive.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox