1 /* GNU/Linux/RISC-V native target description support for GDB. 2 Copyright (C) 2020-2024 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 20 #include "gdb_proc_service.h" 21 #include "arch/riscv.h" 22 #include "elf/common.h" 23 #include "nat/gdb_ptrace.h" 24 #include "nat/riscv-linux-tdesc.h" 25 26 #include <sys/uio.h> 27 28 /* Work around glibc header breakage causing ELF_NFPREG not to be usable. */ 29 #ifndef NFPREG 30 # define NFPREG 33 31 #endif 32 33 /* See nat/riscv-linux-tdesc.h. */ 34 35 struct riscv_gdbarch_features 36 riscv_linux_read_features (int tid) 37 { 38 struct riscv_gdbarch_features features; 39 elf_fpregset_t regs; 40 int flen; 41 42 /* Figuring out xlen is easy. */ 43 features.xlen = sizeof (elf_greg_t); 44 45 /* Start with no f-registers. */ 46 features.flen = 0; 47 48 /* How much worth of f-registers can we fetch if any? */ 49 for (flen = sizeof (regs.__f.__f[0]); ; flen *= 2) 50 { 51 size_t regset_size; 52 struct iovec iov; 53 54 /* Regsets have a uniform slot size, so we count FSCR like 55 an FP data register. */ 56 regset_size = ELF_NFPREG * flen; 57 if (regset_size > sizeof (regs)) 58 break; 59 60 iov.iov_base = ®s; 61 iov.iov_len = regset_size; 62 if (ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, 63 (PTRACE_TYPE_ARG3) &iov) == -1) 64 { 65 switch (errno) 66 { 67 case EINVAL: 68 continue; 69 case EIO: 70 break; 71 default: 72 perror_with_name (_("Couldn't get registers")); 73 break; 74 } 75 } 76 else 77 features.flen = flen; 78 break; 79 } 80 81 return features; 82 } 83