1/* Native-dependent code for NetBSD/sparc64. 2 3 Copyright (C) 2003-2023 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20#include "defs.h" 21#include "gdbcore.h" 22#include "regcache.h" 23#include "target.h" 24 25#include "sparc64-tdep.h" 26#include "sparc-nat.h" 27#include "netbsd-nat.h" 28 29/* NetBSD is different from the other OSes that support both SPARC and 30 UltraSPARC in that the result of ptrace(2) depends on whether the 31 traced process is 32-bit or 64-bit. */ 32 33static void 34sparc64nbsd_supply_gregset (const struct sparc_gregmap *gregmap, 35 struct regcache *regcache, 36 int regnum, const void *gregs) 37{ 38 int sparc32 = (gdbarch_ptr_bit (regcache->arch ()) == 32); 39 40 if (sparc32) 41 sparc32_supply_gregset (&sparc32nbsd_gregmap, regcache, regnum, gregs); 42 else 43 sparc64_supply_gregset (&sparc64nbsd_gregmap, regcache, regnum, gregs); 44} 45 46static void 47sparc64nbsd_collect_gregset (const struct sparc_gregmap *gregmap, 48 const struct regcache *regcache, 49 int regnum, void *gregs) 50{ 51 int sparc32 = (gdbarch_ptr_bit (regcache->arch ()) == 32); 52 53 if (sparc32) 54 sparc32_collect_gregset (&sparc32nbsd_gregmap, regcache, regnum, gregs); 55 else 56 sparc64_collect_gregset (&sparc64nbsd_gregmap, regcache, regnum, gregs); 57} 58 59static void 60sparc64nbsd_supply_fpregset (const struct sparc_fpregmap *fpregmap, 61 struct regcache *regcache, 62 int regnum, const void *fpregs) 63{ 64 int sparc32 = (gdbarch_ptr_bit (regcache->arch ()) == 32); 65 66 if (sparc32) 67 sparc32_supply_fpregset (&sparc32_bsd_fpregmap, regcache, regnum, fpregs); 68 else 69 sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs); 70} 71 72static void 73sparc64nbsd_collect_fpregset (const struct sparc_fpregmap *fpregmap, 74 const struct regcache *regcache, 75 int regnum, void *fpregs) 76{ 77 int sparc32 = (gdbarch_ptr_bit (regcache->arch ()) == 32); 78 79 if (sparc32) 80 sparc32_collect_fpregset (&sparc32_bsd_fpregmap, regcache, regnum, fpregs); 81 else 82 sparc64_collect_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs); 83} 84 85/* Determine whether `gregset_t' contains register REGNUM. */ 86 87static int 88sparc64nbsd_gregset_supplies_p (struct gdbarch *gdbarch, int regnum) 89{ 90 if (gdbarch_ptr_bit (gdbarch) == 32) 91 return sparc32_gregset_supplies_p (gdbarch, regnum); 92 93 /* Integer registers. */ 94 if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_G7_REGNUM) 95 || (regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM) 96 || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_L7_REGNUM) 97 || (regnum >= SPARC_I0_REGNUM && regnum <= SPARC_I7_REGNUM)) 98 return 1; 99 100 /* Control registers. */ 101 if (regnum == SPARC64_PC_REGNUM 102 || regnum == SPARC64_NPC_REGNUM 103 || regnum == SPARC64_STATE_REGNUM 104 || regnum == SPARC64_Y_REGNUM) 105 return 1; 106 107 return 0; 108} 109 110/* Determine whether `fpregset_t' contains register REGNUM. */ 111 112static int 113sparc64nbsd_fpregset_supplies_p (struct gdbarch *gdbarch, int regnum) 114{ 115 if (gdbarch_ptr_bit (gdbarch) == 32) 116 return sparc32_fpregset_supplies_p (gdbarch, regnum); 117 118 /* Floating-point registers. */ 119 if ((regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM) 120 || (regnum >= SPARC64_F32_REGNUM && regnum <= SPARC64_F62_REGNUM)) 121 return 1; 122 123 /* Control registers. */ 124 if (regnum == SPARC64_FSR_REGNUM) 125 return 1; 126 127 return 0; 128} 129 130 131/* Support for debugging kernel virtual memory images. */ 132 133#include <sys/types.h> 134#include <machine/pcb.h> 135 136#include "bsd-kvm.h" 137 138static int 139sparc64nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) 140{ 141 u_int64_t state; 142 int regnum; 143 144 /* The following is true for NetBSD 1.6.2: 145 146 The pcb contains %sp and %pc, %pstate and %cwp. From this 147 information we reconstruct the register state as it would look 148 when we just returned from cpu_switch(). */ 149 150 /* The stack pointer shouldn't be zero. */ 151 if (pcb->pcb_sp == 0) 152 return 0; 153 154 /* If the program counter is zero, this is probably a core dump, and 155 we can get %pc from the stack. */ 156 if (pcb->pcb_pc == 0) 157 read_memory(pcb->pcb_sp + BIAS - 176 + (11 * 8), 158 (gdb_byte *)&pcb->pcb_pc, sizeof pcb->pcb_pc); 159 160 regcache->raw_supply (SPARC_SP_REGNUM, &pcb->pcb_sp); 161 regcache->raw_supply (SPARC64_PC_REGNUM, &pcb->pcb_pc); 162 163 state = pcb->pcb_pstate << 8 | pcb->pcb_cwp; 164 regcache->raw_supply (SPARC64_STATE_REGNUM, &state); 165 166 sparc_supply_rwindow (regcache, pcb->pcb_sp, -1); 167 168 return 1; 169} 170 171/* We've got nothing to add to the generic SPARC target. */ 172static sparc_target<nbsd_nat_target> the_sparc64_nbsd_nat_target; 173 174void _initialize_sparc64nbsd_nat (); 175void 176_initialize_sparc64nbsd_nat () 177{ 178 sparc_supply_gregset = sparc64nbsd_supply_gregset; 179 sparc_collect_gregset = sparc64nbsd_collect_gregset; 180 sparc_supply_fpregset = sparc64nbsd_supply_fpregset; 181 sparc_collect_fpregset = sparc64nbsd_collect_fpregset; 182 sparc_gregset_supplies_p = sparc64nbsd_gregset_supplies_p; 183 sparc_fpregset_supplies_p = sparc64nbsd_fpregset_supplies_p; 184 185 add_inf_child_target (&the_sparc64_nbsd_nat_target); 186 187 /* Support debugging kernel virtual memory images. */ 188 bsd_kvm_add_target (sparc64nbsd_supply_pcb); 189} 190