From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 125996 invoked by alias); 9 Aug 2018 08:42:00 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 125181 invoked by uid 89); 9 Aug 2018 08:41:01 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.3 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.2 spammy= X-HELO: mail-wm0-f68.google.com Received: from mail-wm0-f68.google.com (HELO mail-wm0-f68.google.com) (74.125.82.68) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 09 Aug 2018 08:40:58 +0000 Received: by mail-wm0-f68.google.com with SMTP id w24-v6so5546459wmc.1 for ; Thu, 09 Aug 2018 01:40:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=Vigg1/u1+frhIQsopIOLTyooHhxCkBaTBygVk95iq34=; b=CKpfuHrLn8mNjaG0RPpp+loX5eYmLh8+YY5w+Ujennddbo5W01kx0hdtn/iYn16gUc 8fOvRp/4ILtx98jwuVXmGbHr2FoTIhRubQ0SAGDFmnzmtEk5t3GF3Iub0zJOhPRXYpfq bsHoXGotOSK7sBQC0qjtoZDso+GqqvUmMIGipRDLgzDQvc2hwLqhKFYPQPP08s1/R7Y4 ENfjxpzfPfFg10PWnmf3x0cOSewR43I4T4g3JDJNUFB1HT6VtwuhN4No40Qfj/GF0Hg5 h1ZT6wAQc6q9NflL/6shtuExdhWoTAcmzzjhxhwQ3/QRanmMtPdsEdm4r64xjvhcoMiT AFSw== Return-Path: Received: from localhost (host81-140-215-41.range81-140.btcentralplus.com. [81.140.215.41]) by smtp.gmail.com with ESMTPSA id 188-v6sm9559482wmr.16.2018.08.09.01.40.55 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 09 Aug 2018 01:40:55 -0700 (PDT) Date: Thu, 09 Aug 2018 08:42:00 -0000 From: Andrew Burgess To: Jim Wilson Cc: gdb-patches@sourceware.org Subject: Re: [PATCH 4/5] RISC-V: Add native linux support. Message-ID: <20180809084054.GR3155@embecosm.com> References: <20180808233908.8149-1-jimw@sifive.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20180808233908.8149-1-jimw@sifive.com> X-Fortune: If we do not change our direction we are likely to end up where we are headed. X-Editor: GNU Emacs [ http://www.gnu.org/software/emacs ] User-Agent: Mutt/1.9.2 (2017-12-15) X-IsSubscribed: yes X-SW-Source: 2018-08/txt/msg00207.txt.bz2 * Jim Wilson [2018-08-08 16:39:08 -0700]: > Add initial native support for riscv*-linux*. > > gdb/ > * riscv-linux-nat.c: New file. Looks good to me. Thanks, Andrew > --- > gdb/riscv-linux-nat.c | 280 ++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 280 insertions(+) > create mode 100644 gdb/riscv-linux-nat.c > > diff --git a/gdb/riscv-linux-nat.c b/gdb/riscv-linux-nat.c > new file mode 100644 > index 0000000000..3faa9f9c1f > --- /dev/null > +++ b/gdb/riscv-linux-nat.c > @@ -0,0 +1,280 @@ > +/* Native-dependent code for GNU/Linux RISC-V. > + Copyright (C) 2018 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 "regcache.h" > +#include "gregset.h" > +#include "linux-nat.h" > +#include "elf.h" > +#include "riscv-tdep.h" > + > +#include > + > +/* RISC-V Linux native additions to the default linux support. */ > + > +class riscv_linux_nat_target final : public linux_nat_target > +{ > +public: > + /* Add our register access methods. */ > + void fetch_registers (struct regcache *regcache, int regnum) override; > + void store_registers (struct regcache *regcache, int regnum) override; > +}; > + > +static riscv_linux_nat_target the_riscv_linux_nat_target; > + > +/* Copy general purpose register REGNUM (or all gp regs if REGNUM == -1) > + from regset GREGS into REGCACHE. */ > + > +static void > +supply_gregset_regnum (struct regcache *regcache, const prgregset_t *gregs, > + int regnum) > +{ > + int i; > + const elf_greg_t *regp = *gregs; > + > + if (regnum == -1) > + { > + /* We only support the integer registers and PC here. */ > + for (i = RISCV_ZERO_REGNUM + 1; i < RISCV_PC_REGNUM; i++) > + regcache->raw_supply (i, regp + i); > + > + /* GDB stores PC in reg 32. Linux kernel stores it in reg 0. */ > + regcache->raw_supply (32, regp + 0); > + > + /* Fill the inaccessible zero register with zero. */ > + regcache->raw_supply_zeroed (0); > + } > + else if (regnum == RISCV_ZERO_REGNUM) > + regcache->raw_supply_zeroed (0); > + else if (regnum > RISCV_ZERO_REGNUM && regnum < RISCV_PC_REGNUM) > + regcache->raw_supply (regnum, regp + regnum); > + else if (regnum == RISCV_PC_REGNUM) > + regcache->raw_supply (32, regp + 0); > +} > + > +/* Copy all general purpose registers from regset GREGS into REGCACHE. */ > + > +void > +supply_gregset (struct regcache *regcache, const prgregset_t *gregs) > +{ > + supply_gregset_regnum (regcache, gregs, -1); > +} > + > +/* Copy floating point register REGNUM (or all fp regs if REGNUM == -1) > + from regset FPREGS into REGCACHE. */ > + > +static void > +supply_fpregset_regnum (struct regcache *regcache, const prfpregset_t *fpregs, > + int regnum) > +{ > + int i; > + > + if (regnum == -1) > + { > + /* We only support the FP registers and FCSR here. */ > + for (i = RISCV_FIRST_FP_REGNUM; i <= RISCV_LAST_FP_REGNUM; i++) > + regcache->raw_supply (i, &fpregs->__d.__f[i - RISCV_FIRST_FP_REGNUM]); > + > + regcache->raw_supply (RISCV_CSR_FCSR_REGNUM, &fpregs->__d.__fcsr); > + } > + else if (regnum >= RISCV_FIRST_FP_REGNUM && regnum <= RISCV_LAST_FP_REGNUM) > + regcache->raw_supply (regnum, > + &fpregs->__d.__f[regnum - RISCV_FIRST_FP_REGNUM]); > + else if (regnum == RISCV_CSR_FCSR_REGNUM) > + regcache->raw_supply (RISCV_CSR_FCSR_REGNUM, &fpregs->__d.__fcsr); > +} > + > +/* Copy all floating point registers from regset FPREGS into REGCACHE. */ > + > +void > +supply_fpregset (struct regcache *regcache, const prfpregset_t *fpregs) > +{ > + supply_fpregset_regnum (regcache, fpregs, -1); > +} > + > +/* Copy general purpose register REGNUM (or all gp regs if REGNUM == -1) > + from REGCACHE into regset GREGS. */ > + > +void > +fill_gregset (const struct regcache *regcache, prgregset_t *gregs, int regnum) > +{ > + elf_greg_t *regp = *gregs; > + > + if (regnum == -1) > + { > + /* We only support the integer registers and PC here. */ > + for (int i = RISCV_ZERO_REGNUM + 1; i < RISCV_PC_REGNUM; i++) > + regcache->raw_collect (i, regp + i); > + > + regcache->raw_collect (32, regp + 0); > + } > + else if (regnum == RISCV_ZERO_REGNUM) > + /* Nothing to do here. */ > + ; > + else if (regnum > RISCV_ZERO_REGNUM && regnum < RISCV_PC_REGNUM) > + regcache->raw_collect (regnum, regp + regnum); > + else if (regnum == RISCV_PC_REGNUM) > + regcache->raw_collect (32, regp + 0); > +} > + > +/* Copy floating point register REGNUM (or all fp regs if REGNUM == -1) > + from REGCACHE into regset FPREGS. */ > + > +void > +fill_fpregset (const struct regcache *regcache, prfpregset_t *fpregs, > + int regnum) > +{ > + if (regnum == -1) > + { > + /* We only support the FP registers and FCSR here. */ > + for (int i = RISCV_FIRST_FP_REGNUM; i <= RISCV_LAST_FP_REGNUM; i++) > + regcache->raw_collect (i, &fpregs->__d.__f[i - RISCV_FIRST_FP_REGNUM]); > + > + regcache->raw_collect (RISCV_CSR_FCSR_REGNUM, &fpregs->__d.__fcsr); > + } > + else if (regnum >= RISCV_FIRST_FP_REGNUM && regnum <= RISCV_LAST_FP_REGNUM) > + regcache->raw_collect (regnum, > + &fpregs->__d.__f[regnum - RISCV_FIRST_FP_REGNUM]); > + else if (regnum == RISCV_CSR_FCSR_REGNUM) > + regcache->raw_collect (RISCV_CSR_FCSR_REGNUM, &fpregs->__d.__fcsr); > +} > + > +/* Fetch REGNUM (or all registers if REGNUM == -1) from the target > + into REGCACHE using PTRACE_GETREGSET. */ > + > +void > +riscv_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum) > +{ > + int tid; > + > + tid = get_ptrace_pid (regcache->ptid()); > + > + if ((regnum >= RISCV_ZERO_REGNUM && regnum <= RISCV_PC_REGNUM) > + || (regnum == -1)) > + { > + struct iovec iov; > + elf_gregset_t regs; > + > + iov.iov_base = ®s; > + iov.iov_len = sizeof (regs); > + > + if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, > + (PTRACE_TYPE_ARG3) &iov) == -1) > + perror_with_name (_("Couldn't get registers")); > + else > + supply_gregset_regnum (regcache, ®s, regnum); > + } > + > + if ((regnum >= RISCV_FIRST_FP_REGNUM > + && regnum <= RISCV_LAST_FP_REGNUM) > + || (regnum == RISCV_CSR_FCSR_REGNUM) > + || (regnum == -1)) > + { > + struct iovec iov; > + elf_fpregset_t regs; > + > + iov.iov_base = ®s; > + iov.iov_len = sizeof (regs); > + > + if (ptrace (PTRACE_GETREGSET, tid, NT_PRFPREG, > + (PTRACE_TYPE_ARG3) &iov) == -1) > + perror_with_name (_("Couldn't get registers")); > + else > + supply_fpregset_regnum (regcache, ®s, regnum); > + } > + > + if ((regnum == RISCV_CSR_MISA_REGNUM) > + || (regnum == -1)) > + { > + /* TODO: Need to add a ptrace call for this. */ > + regcache->raw_supply_zeroed (regnum); > + } > + > + /* Access to other CSRs has potential security issues, don't support them for > + now. */ > +} > + > +/* Store REGNUM (or all registers if REGNUM == -1) to the target > + from REGCACHE using PTRACE_SETREGSET. */ > + > +void > +riscv_linux_nat_target::store_registers (struct regcache *regcache, int regnum) > +{ > + int tid; > + > + tid = get_ptrace_pid (regcache->ptid ()); > + > + if ((regnum >= RISCV_ZERO_REGNUM && regnum <= RISCV_PC_REGNUM) > + || (regnum == -1)) > + { > + struct iovec iov; > + elf_gregset_t regs; > + > + iov.iov_base = ®s; > + iov.iov_len = sizeof (regs); > + > + if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, > + (PTRACE_TYPE_ARG3) &iov) == -1) > + perror_with_name (_("Couldn't get registers")); > + else > + { > + fill_gregset (regcache, ®s, regnum); > + > + if (ptrace (PTRACE_SETREGSET, tid, NT_PRSTATUS, > + (PTRACE_TYPE_ARG3) &iov) == -1) > + perror_with_name (_("Couldn't set registers")); > + } > + } > + > + if ((regnum >= RISCV_FIRST_FP_REGNUM > + && regnum <= RISCV_LAST_FP_REGNUM) > + || (regnum == RISCV_CSR_FCSR_REGNUM) > + || (regnum == -1)) > + { > + struct iovec iov; > + elf_fpregset_t regs; > + > + iov.iov_base = ®s; > + iov.iov_len = sizeof (regs); > + > + if (ptrace (PTRACE_GETREGSET, tid, NT_PRFPREG, > + (PTRACE_TYPE_ARG3) &iov) == -1) > + perror_with_name (_("Couldn't get registers")); > + else > + { > + fill_fpregset (regcache, ®s, regnum); > + > + if (ptrace (PTRACE_SETREGSET, tid, NT_PRFPREG, > + (PTRACE_TYPE_ARG3) &iov) == -1) > + perror_with_name (_("Couldn't set registers")); > + } > + } > + > + /* Access to CSRs has potential security issues, don't support them for > + now. */ > +} > + > +/* Initialize RISC-V Linux native support. */ > + > +void > +_initialize_riscv_linux_nat (void) > +{ > + /* Register the target. */ > + linux_target = &the_riscv_linux_nat_target; > + add_inf_child_target (&the_riscv_linux_nat_target); > +} > -- > 2.17.1 >