1 1.1 christos /* Native-dependent code for MIPS systems running NetBSD. 2 1.1 christos 3 1.1.1.2 christos Copyright (C) 2000-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 #include "target.h" 23 1.1 christos 24 1.1 christos #include <sys/types.h> 25 1.1 christos #include <sys/ptrace.h> 26 1.1 christos #include <machine/reg.h> 27 1.1 christos #include <machine/pcb.h> 28 1.1 christos 29 1.1 christos #include "mips-tdep.h" 30 1.1 christos #include "mips-netbsd-tdep.h" 31 1.1 christos #include "netbsd-nat.h" 32 1.1 christos #include "inf-ptrace.h" 33 1.1 christos #include "bsd-kvm.h" 34 1.1 christos 35 1.1 christos class mips_nbsd_nat_target final : public nbsd_nat_target 36 1.1 christos { 37 1.1 christos void fetch_registers (struct regcache *, int) override; 38 1.1 christos void store_registers (struct regcache *, int) override; 39 1.1 christos }; 40 1.1 christos 41 1.1 christos static mips_nbsd_nat_target the_mips_nbsd_nat_target; 42 1.1 christos 43 1.1 christos /* Determine if PT_GETREGS fetches this register. */ 44 1.1 christos static int 45 1.1 christos getregs_supplies (struct gdbarch *gdbarch, int regno) 46 1.1 christos { 47 1.1 christos return ((regno) >= MIPS_ZERO_REGNUM 48 1.1 christos && (regno) <= gdbarch_pc_regnum (gdbarch)); 49 1.1 christos } 50 1.1 christos 51 1.1 christos void 52 1.1 christos mips_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regno) 53 1.1 christos { 54 1.1 christos pid_t pid = regcache->ptid ().pid (); 55 1.1 christos int lwp = regcache->ptid ().lwp (); 56 1.1 christos 57 1.1 christos struct gdbarch *gdbarch = regcache->arch (); 58 1.1 christos if (regno == -1 || getregs_supplies (gdbarch, regno)) 59 1.1 christos { 60 1.1 christos struct reg regs; 61 1.1 christos 62 1.1 christos if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1) 63 1.1 christos perror_with_name (_("Couldn't get registers")); 64 1.1 christos 65 1.1 christos mipsnbsd_supply_reg (regcache, (char *) ®s, regno); 66 1.1 christos if (regno != -1) 67 1.1 christos return; 68 1.1 christos } 69 1.1 christos 70 1.1 christos if (regno == -1 71 1.1 christos || regno >= gdbarch_fp0_regnum (regcache->arch ())) 72 1.1 christos { 73 1.1 christos struct fpreg fpregs; 74 1.1 christos 75 1.1 christos if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1) 76 1.1 christos perror_with_name (_("Couldn't get floating point status")); 77 1.1 christos 78 1.1 christos mipsnbsd_supply_fpreg (regcache, (char *) &fpregs, regno); 79 1.1 christos } 80 1.1 christos } 81 1.1 christos 82 1.1 christos void 83 1.1 christos mips_nbsd_nat_target::store_registers (struct regcache *regcache, int regno) 84 1.1 christos { 85 1.1 christos pid_t pid = regcache->ptid ().pid (); 86 1.1 christos int lwp = regcache->ptid ().lwp (); 87 1.1 christos 88 1.1 christos struct gdbarch *gdbarch = regcache->arch (); 89 1.1 christos if (regno == -1 || getregs_supplies (gdbarch, regno)) 90 1.1 christos { 91 1.1 christos struct reg regs; 92 1.1 christos 93 1.1 christos if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1) 94 1.1 christos perror_with_name (_("Couldn't get registers")); 95 1.1 christos 96 1.1 christos mipsnbsd_fill_reg (regcache, (char *) ®s, regno); 97 1.1 christos 98 1.1 christos if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1) 99 1.1 christos perror_with_name (_("Couldn't write registers")); 100 1.1 christos 101 1.1 christos if (regno != -1) 102 1.1 christos return; 103 1.1 christos } 104 1.1 christos 105 1.1 christos if (regno == -1 106 1.1 christos || regno >= gdbarch_fp0_regnum (regcache->arch ())) 107 1.1 christos { 108 1.1 christos struct fpreg fpregs; 109 1.1 christos 110 1.1 christos if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1) 111 1.1 christos perror_with_name (_("Couldn't get floating point status")); 112 1.1 christos 113 1.1 christos mipsnbsd_fill_fpreg (regcache, (char *) &fpregs, regno); 114 1.1 christos 115 1.1 christos if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1) 116 1.1 christos perror_with_name (_("Couldn't write floating point status")); 117 1.1 christos } 118 1.1 christos } 119 1.1 christos 120 1.1 christos static int 121 1.1 christos mipsnbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) 122 1.1 christos { 123 1.1 christos struct label_t sf; 124 1.1 christos 125 1.1 christos sf = pcb->pcb_context; 126 1.1 christos 127 1.1 christos /* really should test for n{32,64} abi for this register 128 1.1 christos unless this is purely the "n" ABI */ 129 1.1 christos 130 1.1 christos regcache->raw_supply (MIPS_S0_REGNUM, &sf.val[_L_S0]); 131 1.1 christos regcache->raw_supply (MIPS_S1_REGNUM, &sf.val[_L_S1]); 132 1.1 christos regcache->raw_supply (MIPS_S2_REGNUM, &sf.val[_L_S2]); 133 1.1 christos regcache->raw_supply (MIPS_S3_REGNUM, &sf.val[_L_S3]); 134 1.1 christos regcache->raw_supply (MIPS_S4_REGNUM, &sf.val[_L_S4]); 135 1.1 christos regcache->raw_supply (MIPS_S5_REGNUM, &sf.val[_L_S5]); 136 1.1 christos regcache->raw_supply (MIPS_S6_REGNUM, &sf.val[_L_S6]); 137 1.1 christos regcache->raw_supply (MIPS_S7_REGNUM, &sf.val[_L_S7]); 138 1.1 christos 139 1.1 christos regcache->raw_supply (MIPS_S8_REGNUM, &sf.val[_L_S8]); 140 1.1 christos 141 1.1 christos regcache->raw_supply (MIPS_T8_REGNUM, &sf.val[_L_T8]); 142 1.1 christos 143 1.1 christos regcache->raw_supply (MIPS_GP_REGNUM, &sf.val[_L_GP]); 144 1.1 christos 145 1.1 christos regcache->raw_supply (MIPS_SP_REGNUM, &sf.val[_L_SP]); 146 1.1 christos regcache->raw_supply (MIPS_RA_REGNUM, &sf.val[_L_RA]); 147 1.1 christos regcache->raw_supply (MIPS_PS_REGNUM, &sf.val[_L_SR]); 148 1.1 christos 149 1.1 christos /* provide the return address of the savectx as the current pc */ 150 1.1 christos regcache->raw_supply (MIPS_EMBED_PC_REGNUM, &sf.val[_L_RA]); 151 1.1 christos 152 1.1 christos return 0; 153 1.1 christos } 154 1.1 christos 155 1.1 christos void _initialize_mipsnbsd_nat (); 156 1.1 christos void 157 1.1 christos _initialize_mipsnbsd_nat () 158 1.1 christos { 159 1.1 christos add_inf_child_target (&the_mips_nbsd_nat_target); 160 1.1 christos bsd_kvm_add_target (mipsnbsd_supply_pcb); 161 1.1 christos } 162