From patchwork Fri Oct 26 00:00:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Wilson X-Patchwork-Id: 29900 Received: (qmail 50049 invoked by alias); 26 Oct 2018 00:01:43 -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 43952 invoked by uid 89); 26 Oct 2018 00:00:51 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=HX-Received:sk:b12-v6m, sk:__glibc, sk:riscv_i, sk:RISCV_F X-HELO: mail-pf1-f193.google.com Received: from mail-pf1-f193.google.com (HELO mail-pf1-f193.google.com) (209.85.210.193) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 26 Oct 2018 00:00:47 +0000 Received: by mail-pf1-f193.google.com with SMTP id r64-v6so4975216pfb.13 for ; Thu, 25 Oct 2018 17:00:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=p9e/+z5DBYoSE+yqGDcUQ5LSwGTVc6iT5rV3a9j08ug=; b=Y42qN6X2G9268MelvpeJ0B2FU+/ZUyKYq1Jtt0hteY+2HSe8qWfitqjqF9R79Cogx1 HG3676mLE3MZR5Qz/llDItUCuiUA4G4Fu2RQ3ebWfL5Fg+8S0+4o9Aiuabxhbmc/M0lp Xr9agTZfzmwEUrFyIbKYnC82mwQ2YsO3D8YhWRmmNIZsmBe9T/Sa4dG+nb5HOxW1vjMl JyZFzENr+arrA4jcm8w3sewA97R3/8NsHA9HRynqnpFspHOqImtd43kvj9Wc8rsp1LW+ pH/A+lZc2ua5J+dKAX6EAMjolsAPJNuBUmn583Z5XOy8G8PSDIYKnewdH8uDhFiNP2Sh rf9w== Return-Path: Received: from rohan.internal.sifive.com ([12.206.222.5]) by smtp.gmail.com with ESMTPSA id i4-v6sm10854848pgt.4.2018.10.25.17.00.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 25 Oct 2018 17:00:34 -0700 (PDT) From: Jim Wilson To: gdb-patches@sourceware.org Cc: Jim Wilson Subject: [PATCH 2/2] RISC-V: Linux signal frame support. Date: Thu, 25 Oct 2018 17:00:30 -0700 Message-Id: <20181026000030.3847-1-jimw@sifive.com> In-Reply-To: References: 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. */