1 1.1 christos /* Native-dependent code for NetBSD/powerpc. 2 1.1 christos 3 1.1.1.2 christos Copyright (C) 2002-2024 Free Software Foundation, Inc. 4 1.1 christos 5 1.1 christos Contributed by Wasabi Systems, Inc. 6 1.1 christos 7 1.1 christos This file is part of GDB. 8 1.1 christos 9 1.1 christos This program is free software; you can redistribute it and/or modify 10 1.1 christos it under the terms of the GNU General Public License as published by 11 1.1 christos the Free Software Foundation; either version 3 of the License, or 12 1.1 christos (at your option) any later version. 13 1.1 christos 14 1.1 christos This program is distributed in the hope that it will be useful, 15 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 16 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 1.1 christos GNU General Public License for more details. 18 1.1 christos 19 1.1 christos You should have received a copy of the GNU General Public License 20 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 21 1.1 christos 22 1.1 christos #include <sys/types.h> 23 1.1 christos #include <sys/ptrace.h> 24 1.1 christos #include <machine/reg.h> 25 1.1 christos #include <machine/frame.h> 26 1.1 christos #include <machine/pcb.h> 27 1.1 christos 28 1.1 christos #include "gdbcore.h" 29 1.1 christos #include "inferior.h" 30 1.1 christos #include "regcache.h" 31 1.1 christos 32 1.1 christos #include "ppc-tdep.h" 33 1.1 christos #include "ppc-netbsd-tdep.h" 34 1.1 christos #include "bsd-kvm.h" 35 1.1 christos #include "inf-ptrace.h" 36 1.1 christos #include "netbsd-nat.h" 37 1.1 christos 38 1.1 christos struct ppc_nbsd_nat_target final : public nbsd_nat_target 39 1.1 christos { 40 1.1 christos void fetch_registers (struct regcache *, int) override; 41 1.1 christos void store_registers (struct regcache *, int) override; 42 1.1 christos }; 43 1.1 christos 44 1.1 christos static ppc_nbsd_nat_target the_ppc_nbsd_nat_target; 45 1.1 christos 46 1.1 christos /* Returns true if PT_GETREGS fetches this register. */ 47 1.1 christos 48 1.1 christos static int 49 1.1 christos getregs_supplies (struct gdbarch *gdbarch, int regnum) 50 1.1 christos { 51 1.1 christos ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch); 52 1.1 christos 53 1.1 christos return ((regnum >= tdep->ppc_gp0_regnum 54 1.1 christos && regnum < tdep->ppc_gp0_regnum + ppc_num_gprs) 55 1.1 christos || regnum == tdep->ppc_lr_regnum 56 1.1 christos || regnum == tdep->ppc_cr_regnum 57 1.1 christos || regnum == tdep->ppc_xer_regnum 58 1.1 christos || regnum == tdep->ppc_ctr_regnum 59 1.1 christos || regnum == gdbarch_pc_regnum (gdbarch)); 60 1.1 christos } 61 1.1 christos 62 1.1 christos /* Like above, but for PT_GETFPREGS. */ 63 1.1 christos 64 1.1 christos static int 65 1.1 christos getfpregs_supplies (struct gdbarch *gdbarch, int regnum) 66 1.1 christos { 67 1.1 christos ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch); 68 1.1 christos 69 1.1 christos /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating 70 1.1 christos point registers. Traditionally, GDB's register set has still 71 1.1 christos listed the floating point registers for such machines, so this 72 1.1 christos code is harmless. However, the new E500 port actually omits the 73 1.1 christos floating point registers entirely from the register set --- they 74 1.1 christos don't even have register numbers assigned to them. 75 1.1 christos 76 1.1 christos It's not clear to me how best to update this code, so this assert 77 1.1 christos will alert the first person to encounter the NetBSD/E500 78 1.1 christos combination to the problem. */ 79 1.1 christos gdb_assert (ppc_floating_point_unit_p (gdbarch)); 80 1.1 christos 81 1.1 christos return ((regnum >= tdep->ppc_fp0_regnum 82 1.1 christos && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs) 83 1.1 christos || regnum == tdep->ppc_fpscr_regnum); 84 1.1 christos } 85 1.1 christos 86 1.1 christos void 87 1.1 christos ppc_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum) 88 1.1 christos { 89 1.1 christos struct gdbarch *gdbarch = regcache->arch (); 90 1.1 christos pid_t pid = regcache->ptid ().pid (); 91 1.1 christos int lwp = regcache->ptid ().lwp (); 92 1.1 christos 93 1.1 christos if (regnum == -1 || getregs_supplies (gdbarch, regnum)) 94 1.1 christos { 95 1.1 christos struct reg regs; 96 1.1 christos 97 1.1 christos if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1) 98 1.1 christos perror_with_name (_("Couldn't get registers")); 99 1.1 christos 100 1.1 christos ppc_supply_gregset (&ppcnbsd_gregset, regcache, 101 1.1 christos regnum, ®s, sizeof regs); 102 1.1 christos } 103 1.1 christos 104 1.1 christos if (regnum == -1 || getfpregs_supplies (gdbarch, regnum)) 105 1.1 christos { 106 1.1 christos struct fpreg fpregs; 107 1.1 christos 108 1.1 christos if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1) 109 1.1 christos perror_with_name (_("Couldn't get FP registers")); 110 1.1 christos 111 1.1 christos ppc_supply_fpregset (&ppcnbsd_fpregset, regcache, 112 1.1 christos regnum, &fpregs, sizeof fpregs); 113 1.1 christos } 114 1.1 christos } 115 1.1 christos 116 1.1 christos void 117 1.1 christos ppc_nbsd_nat_target::store_registers (struct regcache *regcache, int regnum) 118 1.1 christos { 119 1.1 christos struct gdbarch *gdbarch = regcache->arch (); 120 1.1 christos pid_t pid = regcache->ptid ().pid (); 121 1.1 christos int lwp = regcache->ptid ().lwp (); 122 1.1 christos 123 1.1 christos if (regnum == -1 || getregs_supplies (gdbarch, regnum)) 124 1.1 christos { 125 1.1 christos struct reg regs; 126 1.1 christos 127 1.1 christos if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1) 128 1.1 christos perror_with_name (_("Couldn't get registers")); 129 1.1 christos 130 1.1 christos ppc_collect_gregset (&ppcnbsd_gregset, regcache, 131 1.1 christos regnum, ®s, sizeof regs); 132 1.1 christos 133 1.1 christos if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1) 134 1.1 christos perror_with_name (_("Couldn't write registers")); 135 1.1 christos } 136 1.1 christos 137 1.1 christos if (regnum == -1 || getfpregs_supplies (gdbarch, regnum)) 138 1.1 christos { 139 1.1 christos struct fpreg fpregs; 140 1.1 christos 141 1.1 christos if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1) 142 1.1 christos perror_with_name (_("Couldn't get FP registers")); 143 1.1 christos 144 1.1 christos ppc_collect_fpregset (&ppcnbsd_fpregset, regcache, 145 1.1 christos regnum, &fpregs, sizeof fpregs); 146 1.1 christos 147 1.1 christos if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1) 148 1.1 christos perror_with_name (_("Couldn't set FP registers")); 149 1.1 christos } 150 1.1 christos } 151 1.1 christos 152 1.1 christos static int 153 1.1 christos ppcnbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) 154 1.1 christos { 155 1.1 christos struct switchframe sf; 156 1.1 christos struct callframe cf; 157 1.1 christos struct gdbarch *gdbarch = regcache->arch (); 158 1.1 christos ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch); 159 1.1 christos int i; 160 1.1 christos 161 1.1 christos /* The stack pointer shouldn't be zero. */ 162 1.1 christos if (pcb->pcb_sp == 0) 163 1.1 christos return 0; 164 1.1 christos 165 1.1 christos read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf); 166 1.1 christos regcache->raw_supply (tdep->ppc_cr_regnum, &sf.sf_cr); 167 1.1 christos regcache->raw_supply (tdep->ppc_gp0_regnum + 2, &sf.sf_fixreg2); 168 1.1 christos for (i = 0 ; i < 19 ; i++) 169 1.1 christos regcache->raw_supply (tdep->ppc_gp0_regnum + 13 + i, &sf.sf_fixreg[i]); 170 1.1 christos 171 1.1 christos read_memory(sf.sf_sp, (gdb_byte *)&cf, sizeof(cf)); 172 1.1 christos regcache->raw_supply (tdep->ppc_gp0_regnum + 30, &cf.cf_r30); 173 1.1 christos regcache->raw_supply (tdep->ppc_gp0_regnum + 31, &cf.cf_r31); 174 1.1 christos regcache->raw_supply (tdep->ppc_gp0_regnum + 1, &cf.cf_sp); 175 1.1 christos 176 1.1 christos read_memory(cf.cf_sp, (gdb_byte *)&cf, sizeof(cf)); 177 1.1 christos regcache->raw_supply (tdep->ppc_lr_regnum, &cf.cf_lr); 178 1.1 christos regcache->raw_supply (gdbarch_pc_regnum (gdbarch), &cf.cf_lr); 179 1.1 christos 180 1.1 christos return 1; 181 1.1 christos } 182 1.1 christos 183 1.1 christos void _initialize_ppcnbsd_nat (); 184 1.1 christos void 185 1.1 christos _initialize_ppcnbsd_nat () 186 1.1 christos { 187 1.1 christos /* Support debugging kernel virtual memory images. */ 188 1.1 christos bsd_kvm_add_target (ppcnbsd_supply_pcb); 189 1.1 christos 190 1.1 christos add_inf_child_target (&the_ppc_nbsd_nat_target); 191 1.1 christos } 192