From: John Baldwin <jhb@FreeBSD.org>
To: Jim Wilson <jimw@sifive.com>, gdb-patches@sourceware.org
Subject: Re: [PATCH 2/2] RISC-V: Linux signal frame support.
Date: Fri, 26 Oct 2018 16:26:00 -0000 [thread overview]
Message-ID: <a6620a3e-b77b-550f-c884-704de9f39477@FreeBSD.org> (raw)
In-Reply-To: <20181026000030.3847-1-jimw@sifive.com>
On 10/25/18 5:00 PM, Jim Wilson wrote:
> 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));
FYI, I recently added a new function to the trad_frame interface that lets you
re-use a register map instead of open-coding the layout of registers. In this
case the logic isn't too complex, but you could simplify the handling for the
first register bank to just be:
trad_frame_set_reg_regmap (this_cache, riscv_linux_gregmap, regs_base,
33 * riscv_isa_xlen (gdbarch));
(I added this new function when writing the signal frame unwinder for
riscv-fbsd-tdep.c because I was tired of duplicating the same logic for
various signal frame unwinders.)
You can see an example of this in the riscv_fbsd_sigframe_init() in
riscv-fbsd-tdep.c. (For FreeBSD I also use a register map for the fp
registers since FreeBSD is dumping those in a core dump note as well.)
--
John Baldwin
next prev parent reply other threads:[~2018-10-26 16:26 UTC|newest]
Thread overview: 8+ 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 ` [PATCH 2/2] " Jim Wilson
2018-10-26 3:58 ` Kevin Buettner
2018-10-26 16:26 ` John Baldwin [this message]
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=a6620a3e-b77b-550f-c884-704de9f39477@FreeBSD.org \
--to=jhb@freebsd.org \
--cc=gdb-patches@sourceware.org \
--cc=jimw@sifive.com \
/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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).