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