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