From patchwork Wed Dec 11 16:52:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 36717 Received: (qmail 5652 invoked by alias); 11 Dec 2019 16:52:38 -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 5562 invoked by uid 89); 11 Dec 2019 16:52:38 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-22.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=Supply X-HELO: rock.gnat.com Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 11 Dec 2019 16:52:35 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id D99DF5600F; Wed, 11 Dec 2019 11:52:33 -0500 (EST) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id f5JWD8BW5ERh; Wed, 11 Dec 2019 11:52:33 -0500 (EST) Received: from murgatroyd.Home (75-166-123-50.hlrn.qwest.net [75.166.123.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by rock.gnat.com (Postfix) with ESMTPSA id 9521F5600E; Wed, 11 Dec 2019 11:52:33 -0500 (EST) From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH] Ravenscar port for RISC-V Date: Wed, 11 Dec 2019 09:52:31 -0700 Message-Id: <20191211165231.17943-1-tromey@adacore.com> MIME-Version: 1.0 This adds Ravenscar support to gdb for RISC-V targets. This was tested internally using AdaCore's test suite and qemu. gdb/ChangeLog 2019-12-11 Tom Tromey * Makefile.in (ALL_TARGET_OBS): Add riscv-ravenscar-thread.o. (HFILES_NO_SRCDIR): Add riscv-ravenscar-thread.h. (ALLDEPFILES): Add riscv-ravenscar-thread.c. * configure.tgt (riscv-*-*): Add riscv-ravenscar-thread.o. * riscv-ravenscar-thread.c: New file. * riscv-ravenscar-thread.h: New file. * riscv-tdep.c (riscv_gdbarch_init): Call register_riscv_ravenscar_ops. Change-Id: Ic47a3b3cfbbe80c2c82a5f48d2e0481845cac8b0 --- gdb/ChangeLog | 11 +++ gdb/Makefile.in | 3 + gdb/configure.tgt | 3 +- gdb/riscv-ravenscar-thread.c | 140 +++++++++++++++++++++++++++++++++++ gdb/riscv-ravenscar-thread.h | 27 +++++++ gdb/riscv-tdep.c | 3 + 6 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 gdb/riscv-ravenscar-thread.c create mode 100644 gdb/riscv-ravenscar-thread.h diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 67fa1dfa90a..fa5c820b918 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -777,6 +777,7 @@ ALL_TARGET_OBS = \ ravenscar-thread.o \ riscv-fbsd-tdep.o \ riscv-linux-tdep.o \ + riscv-ravenscar-thread.o \ riscv-tdep.o \ rl78-tdep.o \ rs6000-aix-tdep.o \ @@ -1380,6 +1381,7 @@ HFILES_NO_SRCDIR = \ remote-fileio.h \ remote-notif.h \ riscv-fbsd-tdep.h \ + riscv-ravenscar-thread.h \ riscv-tdep.h \ rs6000-aix-tdep.h \ rs6000-tdep.h \ @@ -2299,6 +2301,7 @@ ALLDEPFILES = \ riscv-fbsd-tdep.c \ riscv-linux-nat.c \ riscv-linux-tdep.c \ + riscv-ravenscar-thread.c \ riscv-tdep.c \ rl78-tdep.c \ rs6000-lynx178-tdep.c \ diff --git a/gdb/configure.tgt b/gdb/configure.tgt index caa42be1c01..b3717c7a80c 100644 --- a/gdb/configure.tgt +++ b/gdb/configure.tgt @@ -85,7 +85,8 @@ ia64*-*-*) ;; riscv*-*-*) - cpu_obs="riscv-tdep.o arch/riscv.o";; + cpu_obs="riscv-tdep.o arch/riscv.o \ + ravenscar-thread.o riscv-ravenscar-thread.o";; x86_64-*-*) cpu_obs="${i386_tobjs} ${amd64_tobjs}";; diff --git a/gdb/riscv-ravenscar-thread.c b/gdb/riscv-ravenscar-thread.c new file mode 100644 index 00000000000..d6b34e5b8cb --- /dev/null +++ b/gdb/riscv-ravenscar-thread.c @@ -0,0 +1,140 @@ +/* Ravenscar RISC-V target support. + + Copyright (C) 2019 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "defs.h" +#include "gdbarch.h" +#include "gdbcore.h" +#include "regcache.h" +#include "riscv-tdep.h" +#include "inferior.h" +#include "ravenscar-thread.h" +#include "riscv-ravenscar-thread.h" + +struct riscv_ravenscar_ops : public ravenscar_arch_ops +{ + void fetch_registers (struct regcache *regcache, int regnum) override; + void store_registers (struct regcache *regcache, int regnum) override; + +private: + + /* Return the offset of the register in the context buffer. */ + int register_offset (struct gdbarch *arch, int regnum); +}; + +int +riscv_ravenscar_ops::register_offset (struct gdbarch *arch, int regnum) +{ + int offset; + if (regnum == RISCV_RA_REGNUM || regnum == RISCV_PC_REGNUM) + offset = 0; + else if (regnum == RISCV_SP_REGNUM) + offset = 1; + else if (regnum == RISCV_ZERO_REGNUM + 8) /* S0 */ + offset = 2; + else if (regnum == RISCV_ZERO_REGNUM + 9) /* S1 */ + offset = 3; + else if (regnum >= RISCV_ZERO_REGNUM + 19 + && regnum <= RISCV_ZERO_REGNUM + 27) /* S2..S11 */ + offset = regnum - (RISCV_ZERO_REGNUM + 19) + 4; + else if (regnum >= RISCV_FIRST_FP_REGNUM + && regnum <= RISCV_FIRST_FP_REGNUM + 11) + offset = regnum - RISCV_FIRST_FP_REGNUM + 14; /* FS0..FS11 */ + else + { + /* Not saved. */ + return -1; + } + + int size = register_size (arch, regnum); + return offset * size; +} + +/* Supply register REGNUM, which has been saved on REGISTER_ADDR, to the + regcache. */ + +static void +supply_register_at_address (struct regcache *regcache, int regnum, + CORE_ADDR register_addr) +{ + struct gdbarch *gdbarch = regcache->arch (); + int buf_size = register_size (gdbarch, regnum); + gdb_byte *buf; + + buf = (gdb_byte *) alloca (buf_size); + read_memory (register_addr, buf, buf_size); + regcache->raw_supply (regnum, buf); +} + +void +riscv_ravenscar_ops::fetch_registers (struct regcache *regcache, int regnum) +{ + struct gdbarch *gdbarch = regcache->arch (); + const int num_regs = gdbarch_num_regs (gdbarch); + int current_regnum; + CORE_ADDR current_address; + CORE_ADDR thread_descriptor_address; + + /* The tid is the thread_id field, which is a pointer to the thread. */ + thread_descriptor_address = (CORE_ADDR) inferior_ptid.tid (); + + /* Read registers. */ + for (current_regnum = 0; current_regnum < num_regs; current_regnum++) + { + int offset = register_offset (gdbarch, current_regnum); + + if (offset != -1) + { + current_address = thread_descriptor_address + offset; + supply_register_at_address (regcache, current_regnum, + current_address); + } + } +} + +void +riscv_ravenscar_ops::store_registers (struct regcache *regcache, int regnum) +{ + struct gdbarch *gdbarch = regcache->arch (); + int buf_size = register_size (gdbarch, regnum); + gdb_byte buf[buf_size]; + CORE_ADDR register_address; + + int offset = register_offset (gdbarch, regnum); + if (offset != -1) + { + register_address = inferior_ptid.tid () + offset; + + regcache->raw_collect (regnum, buf); + write_memory (register_address, + buf, + buf_size); + } +} + +/* The ravenscar_arch_ops vector for most RISC-V targets. */ + +static struct riscv_ravenscar_ops riscv_ravenscar_ops; + +/* Register riscv_ravenscar_ops in GDBARCH. */ + +void +register_riscv_ravenscar_ops (struct gdbarch *gdbarch) +{ + set_gdbarch_ravenscar_ops (gdbarch, &riscv_ravenscar_ops); +} diff --git a/gdb/riscv-ravenscar-thread.h b/gdb/riscv-ravenscar-thread.h new file mode 100644 index 00000000000..d360ad7417a --- /dev/null +++ b/gdb/riscv-ravenscar-thread.h @@ -0,0 +1,27 @@ +/* Ravenscar RISC-V target support. + + Copyright (C) 2019 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef RISCV_RAVENSCAR_THREAD_H +#define RISCV_RAVENSCAR_THREAD_H + +struct gdbarch; + +extern void register_riscv_ravenscar_ops (struct gdbarch *gdbarch); + +#endif diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c index d262b7d07e7..a8b057f622b 100644 --- a/gdb/riscv-tdep.c +++ b/gdb/riscv-tdep.c @@ -56,6 +56,7 @@ #include "observable.h" #include "prologue-value.h" #include "arch/riscv.h" +#include "riscv-ravenscar-thread.h" /* The stack must be 16-byte aligned. */ #define SP_ALIGNMENT 16 @@ -3358,6 +3359,8 @@ riscv_gdbarch_init (struct gdbarch_info info, /* Hook in OS ABI-specific overrides, if they have been registered. */ gdbarch_init_osabi (info, gdbarch); + register_riscv_ravenscar_ops (gdbarch); + return gdbarch; }