1 /* GNU/Linux/RISC-V native target description support for GDB. 2 Copyright (C) 2020-2021 Free Software Foundation, Inc. 3 4 This file is part of GDB. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 19 #include "gdbsupport/common-defs.h" 20 21 #include "gdb_proc_service.h" 22 #include "arch/riscv.h" 23 #include "elf/common.h" 24 #include "nat/gdb_ptrace.h" 25 #include "nat/riscv-linux-tdesc.h" 26 27 #include <sys/uio.h> 28 29 /* Work around glibc header breakage causing ELF_NFPREG not to be usable. */ 30 #ifndef NFPREG 31 # define NFPREG 33 32 #endif 33 34 /* See nat/riscv-linux-tdesc.h. */ 35 36 struct riscv_gdbarch_features riscv_linux_read_features(int tid)37riscv_linux_read_features (int tid) 38 { 39 struct riscv_gdbarch_features features; 40 elf_fpregset_t regs; 41 int flen; 42 43 /* Figuring out xlen is easy. */ 44 features.xlen = sizeof (elf_greg_t); 45 46 /* Start with no f-registers. */ 47 features.flen = 0; 48 49 /* How much worth of f-registers can we fetch if any? */ 50 for (flen = sizeof (regs.__f.__f[0]); ; flen *= 2) 51 { 52 size_t regset_size; 53 struct iovec iov; 54 55 /* Regsets have a uniform slot size, so we count FSCR like 56 an FP data register. */ 57 regset_size = ELF_NFPREG * flen; 58 if (regset_size > sizeof (regs)) 59 break; 60 61 iov.iov_base = ®s; 62 iov.iov_len = regset_size; 63 if (ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, 64 (PTRACE_TYPE_ARG3) &iov) == -1) 65 { 66 switch (errno) 67 { 68 case EINVAL: 69 continue; 70 case EIO: 71 break; 72 default: 73 perror_with_name (_("Couldn't get registers")); 74 break; 75 } 76 } 77 else 78 features.flen = flen; 79 break; 80 } 81 82 return features; 83 } 84