X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Friscv-linux-nat.c;h=4f78dfdc6a20f447863b1821a598c0434afaa5e7;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=c09121d052b662fcee27fed559ec1a3608d5388a;hpb=ee67fd7f3f6ca78eede2862e309c0bcf266bbd7e;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/riscv-linux-nat.c b/gdb/riscv-linux-nat.c index c09121d052..4f78dfdc6a 100644 --- a/gdb/riscv-linux-nat.c +++ b/gdb/riscv-linux-nat.c @@ -1,5 +1,5 @@ /* Native-dependent code for GNU/Linux RISC-V. - Copyright (C) 2018 Free Software Foundation, Inc. + Copyright (C) 2018-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -21,11 +21,19 @@ #include "gregset.h" #include "linux-nat.h" #include "riscv-tdep.h" +#include "inferior.h" #include "elf/common.h" +#include "nat/riscv-linux-tdesc.h" + #include +/* Work around glibc header breakage causing ELF_NFPREG not to be usable. */ +#ifndef NFPREG +# define NFPREG 33 +#endif + /* RISC-V Linux native additions to the default linux support. */ class riscv_linux_nat_target final : public linux_nat_target @@ -34,6 +42,9 @@ public: /* Add our register access methods. */ void fetch_registers (struct regcache *regcache, int regnum) override; void store_registers (struct regcache *regcache, int regnum) override; + + /* Read suitable target description. */ + const struct target_desc *read_description () override; }; static riscv_linux_nat_target the_riscv_linux_nat_target; @@ -83,21 +94,35 @@ static void supply_fpregset_regnum (struct regcache *regcache, const prfpregset_t *fpregs, int regnum) { + int flen = register_size (regcache->arch (), RISCV_FIRST_FP_REGNUM); + union + { + const prfpregset_t *fpregs; + const gdb_byte *buf; + } + fpbuf = { .fpregs = fpregs }; 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]); + for (i = RISCV_FIRST_FP_REGNUM; + i <= RISCV_LAST_FP_REGNUM; + i++, fpbuf.buf += flen) + regcache->raw_supply (i, fpbuf.buf); - regcache->raw_supply (RISCV_CSR_FCSR_REGNUM, &fpregs->__d.__fcsr); + regcache->raw_supply (RISCV_CSR_FCSR_REGNUM, fpbuf.buf); } else if (regnum >= RISCV_FIRST_FP_REGNUM && regnum <= RISCV_LAST_FP_REGNUM) - regcache->raw_supply (regnum, - &fpregs->__d.__f[regnum - RISCV_FIRST_FP_REGNUM]); + { + fpbuf.buf += flen * (regnum - RISCV_FIRST_FP_REGNUM); + regcache->raw_supply (regnum, fpbuf.buf); + } else if (regnum == RISCV_CSR_FCSR_REGNUM) - regcache->raw_supply (RISCV_CSR_FCSR_REGNUM, &fpregs->__d.__fcsr); + { + fpbuf.buf += flen * (RISCV_LAST_FP_REGNUM - RISCV_FIRST_FP_REGNUM + 1); + regcache->raw_supply (RISCV_CSR_FCSR_REGNUM, fpbuf.buf); + } } /* Copy all floating point registers from regset FPREGS into REGCACHE. */ @@ -140,19 +165,45 @@ void fill_fpregset (const struct regcache *regcache, prfpregset_t *fpregs, int regnum) { + int flen = register_size (regcache->arch (), RISCV_FIRST_FP_REGNUM); + union + { + prfpregset_t *fpregs; + gdb_byte *buf; + } + fpbuf = { .fpregs = fpregs }; + int i; + 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]); + for (i = RISCV_FIRST_FP_REGNUM; + i <= RISCV_LAST_FP_REGNUM; + i++, fpbuf.buf += flen) + regcache->raw_collect (i, fpbuf.buf); - regcache->raw_collect (RISCV_CSR_FCSR_REGNUM, &fpregs->__d.__fcsr); + regcache->raw_collect (RISCV_CSR_FCSR_REGNUM, fpbuf.buf); } else if (regnum >= RISCV_FIRST_FP_REGNUM && regnum <= RISCV_LAST_FP_REGNUM) - regcache->raw_collect (regnum, - &fpregs->__d.__f[regnum - RISCV_FIRST_FP_REGNUM]); + { + fpbuf.buf += flen * (regnum - RISCV_FIRST_FP_REGNUM); + regcache->raw_collect (regnum, fpbuf.buf); + } else if (regnum == RISCV_CSR_FCSR_REGNUM) - regcache->raw_collect (RISCV_CSR_FCSR_REGNUM, &fpregs->__d.__fcsr); + { + fpbuf.buf += flen * (RISCV_LAST_FP_REGNUM - RISCV_FIRST_FP_REGNUM + 1); + regcache->raw_collect (RISCV_CSR_FCSR_REGNUM, fpbuf.buf); + } +} + +/* Return a target description for the current target. */ + +const struct target_desc * +riscv_linux_nat_target::read_description () +{ + const struct riscv_gdbarch_features features + = riscv_linux_read_features (inferior_ptid.lwp ()); + return riscv_lookup_target_description (features); } /* Fetch REGNUM (or all registers if REGNUM == -1) from the target @@ -190,7 +241,9 @@ riscv_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum) elf_fpregset_t regs; iov.iov_base = ®s; - iov.iov_len = sizeof (regs); + iov.iov_len = ELF_NFPREG * register_size (regcache->arch (), + RISCV_FIRST_FP_REGNUM); + gdb_assert (iov.iov_len <= sizeof (regs)); if (ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, (PTRACE_TYPE_ARG3) &iov) == -1) @@ -201,8 +254,10 @@ riscv_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum) if ((regnum == RISCV_CSR_MISA_REGNUM) || (regnum == -1)) - /* TODO: Need to add a ptrace call for this. */ - regcache->raw_supply_zeroed (RISCV_CSR_MISA_REGNUM); + { + /* TODO: Need to add a ptrace call for this. */ + regcache->raw_supply_zeroed (RISCV_CSR_MISA_REGNUM); + } /* Access to other CSRs has potential security issues, don't support them for now. */ @@ -249,7 +304,9 @@ riscv_linux_nat_target::store_registers (struct regcache *regcache, int regnum) elf_fpregset_t regs; iov.iov_base = ®s; - iov.iov_len = sizeof (regs); + iov.iov_len = ELF_NFPREG * register_size (regcache->arch (), + RISCV_FIRST_FP_REGNUM); + gdb_assert (iov.iov_len <= sizeof (regs)); if (ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, (PTRACE_TYPE_ARG3) &iov) == -1) @@ -270,8 +327,9 @@ riscv_linux_nat_target::store_registers (struct regcache *regcache, int regnum) /* Initialize RISC-V Linux native support. */ +void _initialize_riscv_linux_nat (); void -_initialize_riscv_linux_nat (void) +_initialize_riscv_linux_nat () { /* Register the target. */ linux_target = &the_riscv_linux_nat_target;