1 1.1 christos /* Native-dependent code for NetBSD/hppa. 2 1.1 christos 3 1.1.1.2 christos Copyright (C) 2008-2024 Free Software Foundation, Inc. 4 1.1 christos 5 1.1 christos This file is part of GDB. 6 1.1 christos 7 1.1 christos This program is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3 of the License, or 10 1.1 christos (at your option) any later version. 11 1.1 christos 12 1.1 christos This program is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 1.1 christos 20 1.1 christos #include "inferior.h" 21 1.1 christos #include "regcache.h" 22 1.1 christos 23 1.1 christos #include <sys/types.h> 24 1.1 christos #include <sys/ptrace.h> 25 1.1 christos #include <machine/reg.h> 26 1.1 christos 27 1.1 christos #include "hppa-tdep.h" 28 1.1 christos #include "inf-ptrace.h" 29 1.1 christos 30 1.1 christos #include "netbsd-nat.h" 31 1.1 christos 32 1.1 christos class hppa_nbsd_nat_target final : public nbsd_nat_target 33 1.1 christos { 34 1.1 christos void fetch_registers (struct regcache *, int) override; 35 1.1 christos void store_registers (struct regcache *, int) override; 36 1.1 christos }; 37 1.1 christos 38 1.1 christos static hppa_nbsd_nat_target the_hppa_nbsd_nat_target; 39 1.1 christos 40 1.1 christos static int 41 1.1 christos hppanbsd_gregset_supplies_p (int regnum) 42 1.1 christos { 43 1.1 christos return ((regnum >= HPPA_R0_REGNUM && regnum <= HPPA_R31_REGNUM) || 44 1.1 christos (regnum >= HPPA_SAR_REGNUM && regnum <= HPPA_PCSQ_TAIL_REGNUM) || 45 1.1 christos regnum == HPPA_IPSW_REGNUM || 46 1.1 christos (regnum >= HPPA_SR4_REGNUM && regnum <= HPPA_SR4_REGNUM + 5)); 47 1.1 christos } 48 1.1 christos 49 1.1 christos static int 50 1.1 christos hppanbsd_fpregset_supplies_p (int regnum) 51 1.1 christos { 52 1.1 christos return (regnum >= HPPA_FP0_REGNUM && regnum <= HPPA_FP31R_REGNUM); 53 1.1 christos } 54 1.1 christos 55 1.1 christos /* Supply the general-purpose registers stored in GREGS to REGCACHE. */ 56 1.1 christos 57 1.1 christos static void 58 1.1 christos hppanbsd_supply_gregset (struct regcache *regcache, const void *gregs) 59 1.1 christos { 60 1.1 christos const char *regs = (const char *)gregs; 61 1.1 christos int regnum; 62 1.1 christos 63 1.1 christos for (regnum = HPPA_R1_REGNUM; regnum <= HPPA_R31_REGNUM; regnum++) 64 1.1 christos regcache->raw_supply (regnum, regs + regnum * 4); 65 1.1 christos 66 1.1 christos regcache->raw_supply (HPPA_SAR_REGNUM, regs + 32 * 4); 67 1.1 christos regcache->raw_supply (HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4); 68 1.1 christos regcache->raw_supply (HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4); 69 1.1 christos regcache->raw_supply (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4); 70 1.1 christos regcache->raw_supply (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4); 71 1.1 christos regcache->raw_supply (HPPA_IPSW_REGNUM, regs); 72 1.1 christos regcache->raw_supply (HPPA_SR4_REGNUM, regs + 41 * 4); 73 1.1 christos regcache->raw_supply (HPPA_SR4_REGNUM + 1, regs + 37 * 4); 74 1.1 christos regcache->raw_supply (HPPA_SR4_REGNUM + 2, regs + 38 * 4); 75 1.1 christos regcache->raw_supply (HPPA_SR4_REGNUM + 3, regs + 39 * 4); 76 1.1 christos regcache->raw_supply (HPPA_SR4_REGNUM + 4, regs + 40 * 4); 77 1.1 christos } 78 1.1 christos 79 1.1 christos /* Supply the floating-point registers stored in FPREGS to REGCACHE. */ 80 1.1 christos 81 1.1 christos static void 82 1.1 christos hppanbsd_supply_fpregset (struct regcache *regcache, const void *fpregs) 83 1.1 christos { 84 1.1 christos const char *regs = (const char *)fpregs; 85 1.1 christos int regnum; 86 1.1 christos 87 1.1 christos for (regnum = HPPA_FP0_REGNUM; regnum <= HPPA_FP31R_REGNUM; 88 1.1 christos regnum += 2, regs += 8) 89 1.1 christos { 90 1.1 christos regcache->raw_supply (regnum, regs); 91 1.1 christos regcache->raw_supply (regnum + 1, regs + 4); 92 1.1 christos } 93 1.1 christos } 94 1.1 christos 95 1.1 christos /* Collect the general-purpose registers from REGCACHE and store them 96 1.1 christos in GREGS. */ 97 1.1 christos 98 1.1 christos static void 99 1.1 christos hppanbsd_collect_gregset (const struct regcache *regcache, 100 1.1 christos void *gregs, int regnum) 101 1.1 christos { 102 1.1 christos char *regs = (char *)gregs; 103 1.1 christos int i; 104 1.1 christos 105 1.1 christos for (i = HPPA_R1_REGNUM; i <= HPPA_R31_REGNUM; i++) 106 1.1 christos { 107 1.1 christos if (regnum == -1 || regnum == i) 108 1.1 christos regcache->raw_collect (i, regs + i * 4); 109 1.1 christos } 110 1.1 christos 111 1.1 christos if (regnum == -1 || regnum == HPPA_IPSW_REGNUM) 112 1.1 christos regcache->raw_collect (HPPA_IPSW_REGNUM, regs); 113 1.1 christos if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM) 114 1.1 christos regcache->raw_collect (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4); 115 1.1 christos if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM) 116 1.1 christos regcache->raw_collect (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4); 117 1.1 christos 118 1.1 christos if (regnum == -1 || regnum == HPPA_SAR_REGNUM) 119 1.1 christos regcache->raw_collect (HPPA_SAR_REGNUM, regs + 32 * 4); 120 1.1 christos if (regnum == -1 || regnum == HPPA_PCSQ_HEAD_REGNUM) 121 1.1 christos regcache->raw_collect (HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4); 122 1.1 christos if (regnum == -1 || regnum == HPPA_PCSQ_TAIL_REGNUM) 123 1.1 christos regcache->raw_collect (HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4); 124 1.1 christos if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM) 125 1.1 christos regcache->raw_collect (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4); 126 1.1 christos if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM) 127 1.1 christos regcache->raw_collect (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4); 128 1.1 christos if (regnum == -1 || regnum == HPPA_IPSW_REGNUM) 129 1.1 christos regcache->raw_collect (HPPA_IPSW_REGNUM, regs); 130 1.1 christos if (regnum == -1 || regnum == HPPA_SR4_REGNUM) 131 1.1 christos regcache->raw_collect (HPPA_SR4_REGNUM, regs + 41 * 4); 132 1.1 christos if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 1) 133 1.1 christos regcache->raw_collect (HPPA_SR4_REGNUM + 1, regs + 37 * 4); 134 1.1 christos if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 2) 135 1.1 christos regcache->raw_collect (HPPA_SR4_REGNUM + 2, regs + 38 * 4); 136 1.1 christos if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 3) 137 1.1 christos regcache->raw_collect (HPPA_SR4_REGNUM + 3, regs + 39 * 4); 138 1.1 christos if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 4) 139 1.1 christos regcache->raw_collect (HPPA_SR4_REGNUM + 4, regs + 40 * 4); 140 1.1 christos } 141 1.1 christos 142 1.1 christos /* Collect the floating-point registers from REGCACHE and store them 143 1.1 christos in FPREGS. */ 144 1.1 christos 145 1.1 christos static void 146 1.1 christos hppanbsd_collect_fpregset (const struct regcache *regcache, 147 1.1 christos void *fpregs, int regnum) 148 1.1 christos { 149 1.1 christos char *regs = (char *)fpregs; 150 1.1 christos int i; 151 1.1 christos 152 1.1 christos for (i = HPPA_FP0_REGNUM; i <= HPPA_FP31R_REGNUM; i += 2, regs += 8) 153 1.1 christos { 154 1.1 christos if (regnum == -1 || regnum == i || regnum == i + 1) 155 1.1 christos { 156 1.1 christos regcache->raw_collect (i, regs); 157 1.1 christos regcache->raw_collect (i + 1, regs + 4); 158 1.1 christos } 159 1.1 christos } 160 1.1 christos } 161 1.1 christos 162 1.1 christos 164 1.1 christos /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this 165 1.1 christos for all registers (including the floating-point registers). */ 166 1.1 christos 167 1.1 christos void 168 1.1 christos hppa_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum) 169 1.1 christos 170 1.1 christos { 171 1.1 christos pid_t pid = regcache->ptid ().pid (); 172 1.1 christos int lwp = regcache->ptid ().lwp (); 173 1.1 christos 174 1.1 christos if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum)) 175 1.1 christos { 176 1.1 christos struct reg regs; 177 1.1 christos 178 1.1 christos if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1) 179 1.1 christos perror_with_name (_("Couldn't get registers")); 180 1.1 christos 181 1.1 christos hppanbsd_supply_gregset (regcache, ®s); 182 1.1 christos } 183 1.1 christos 184 1.1 christos if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum)) 185 1.1 christos { 186 1.1 christos struct fpreg fpregs; 187 1.1 christos 188 1.1 christos if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1) 189 1.1 christos perror_with_name (_("Couldn't get floating point status")); 190 1.1 christos 191 1.1 christos hppanbsd_supply_fpregset (regcache, &fpregs); 192 1.1 christos } 193 1.1 christos } 194 1.1 christos 195 1.1 christos /* Store register REGNUM back into the inferior. If REGNUM is -1, do 196 1.1 christos this for all registers (including the floating-point registers). */ 197 1.1 christos 198 1.1 christos void 199 1.1 christos hppa_nbsd_nat_target::store_registers (struct regcache *regcache, int regnum) 200 1.1 christos { 201 1.1 christos pid_t pid = regcache->ptid ().pid (); 202 1.1 christos int lwp = regcache->ptid ().lwp (); 203 1.1 christos 204 1.1 christos if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum)) 205 1.1 christos { 206 1.1 christos struct reg regs; 207 1.1 christos 208 1.1 christos if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1) 209 1.1 christos perror_with_name (_("Couldn't get registers")); 210 1.1 christos 211 1.1 christos hppanbsd_collect_gregset (regcache, ®s, regnum); 212 1.1 christos 213 1.1 christos if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1) 214 1.1 christos perror_with_name (_("Couldn't write registers")); 215 1.1 christos } 216 1.1 christos 217 1.1 christos if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum)) 218 1.1 christos { 219 1.1 christos struct fpreg fpregs; 220 1.1 christos 221 1.1 christos if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1) 222 1.1 christos perror_with_name (_("Couldn't get floating point status")); 223 1.1 christos 224 1.1 christos hppanbsd_collect_fpregset (regcache, &fpregs, regnum); 225 1.1 christos 226 1.1 christos if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1) 227 1.1 christos perror_with_name (_("Couldn't write floating point status")); 228 1.1 christos } 229 1.1 christos } 230 1.1 christos 231 1.1 christos void _initialize_hppanbsd_nat (); 232 1.1 christos void 233 1.1 christos _initialize_hppanbsd_nat () 234 1.1 christos { 235 1.1 christos add_inf_child_target (&the_hppa_nbsd_nat_target); 236 } 237