gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / hppa-nbsd-nat.c
CommitLineData
af5ca30d
NH
1/* Native-dependent code for NetBSD/hppa.
2
b811d2c2 3 Copyright (C) 2008-2020 Free Software Foundation, Inc.
af5ca30d
NH
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
5b1ba0e5 9 the Free Software Foundation; either version 3 of the License, or
af5ca30d
NH
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
5b1ba0e5 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
af5ca30d
NH
19
20#include "defs.h"
21#include "inferior.h"
22#include "regcache.h"
23
24#include <sys/types.h>
25#include <sys/ptrace.h>
26#include <machine/reg.h>
27
28#include "hppa-tdep.h"
29#include "inf-ptrace.h"
30
31#include "nbsd-nat.h"
32
f6ac5f3d
PA
33class hppa_nbsd_nat_target final : public nbsd_nat_target
34{
35 void fetch_registers (struct regcache *, int) override;
36 void store_registers (struct regcache *, int) override;
37};
38
39static hppa_nbsd_nat_target the_hppa_nbsd_nat_target;
40
af5ca30d
NH
41static int
42hppanbsd_gregset_supplies_p (int regnum)
43{
44 return ((regnum >= HPPA_R0_REGNUM && regnum <= HPPA_R31_REGNUM) ||
45 (regnum >= HPPA_SAR_REGNUM && regnum <= HPPA_PCSQ_TAIL_REGNUM) ||
46 regnum == HPPA_IPSW_REGNUM ||
47 (regnum >= HPPA_SR4_REGNUM && regnum <= HPPA_SR4_REGNUM + 5));
48}
49
50static int
51hppanbsd_fpregset_supplies_p (int regnum)
52{
53 return (regnum >= HPPA_FP0_REGNUM && regnum <= HPPA_FP31R_REGNUM);
54}
55
56/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
57
58static void
59hppanbsd_supply_gregset (struct regcache *regcache, const void *gregs)
60{
61 const char *regs = gregs;
62 const int *r = gregs;
63 int regnum;
64
65 for (regnum = HPPA_R1_REGNUM; regnum <= HPPA_R31_REGNUM; regnum++)
73e1c03f
SM
66 regcache->raw_supply (regnum, regs + regnum * 4);
67
68 regcache->raw_supply (HPPA_SAR_REGNUM, regs + 32 * 4);
69 regcache->raw_supply (HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
70 regcache->raw_supply (HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
71 regcache->raw_supply (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
72 regcache->raw_supply (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
73 regcache->raw_supply (HPPA_IPSW_REGNUM, regs);
74 regcache->raw_supply (HPPA_SR4_REGNUM, regs + 41 * 4);
75 regcache->raw_supply (HPPA_SR4_REGNUM + 1, regs + 37 * 4);
76 regcache->raw_supply (HPPA_SR4_REGNUM + 2, regs + 38 * 4);
77 regcache->raw_supply (HPPA_SR4_REGNUM + 3, regs + 39 * 4);
78 regcache->raw_supply (HPPA_SR4_REGNUM + 4, regs + 40 * 4);
af5ca30d
NH
79}
80
81/* Supply the floating-point registers stored in FPREGS to REGCACHE. */
82
83static void
84hppanbsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
85{
86 const char *regs = fpregs;
87 int regnum;
88
89 for (regnum = HPPA_FP0_REGNUM; regnum <= HPPA_FP31R_REGNUM;
90 regnum += 2, regs += 8)
91 {
73e1c03f
SM
92 regcache->raw_supply (regnum, regs);
93 regcache->raw_supply (regnum + 1, regs + 4);
af5ca30d
NH
94 }
95}
96
97/* Collect the general-purpose registers from REGCACHE and store them
98 in GREGS. */
99
100static void
101hppanbsd_collect_gregset (const struct regcache *regcache,
102 void *gregs, int regnum)
103{
104 char *regs = gregs;
105 int *r = gregs;
106 int i;
107
108 for (i = HPPA_R1_REGNUM; i <= HPPA_R31_REGNUM; i++)
109 {
110 if (regnum == -1 || regnum == i)
34a79281 111 regcache->raw_collect (i, regs + i * 4);
af5ca30d
NH
112 }
113
114 if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
34a79281 115 regcache->raw_collect (HPPA_IPSW_REGNUM, regs);
af5ca30d 116 if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
34a79281 117 regcache->raw_collect (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
af5ca30d 118 if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
34a79281 119 regcache->raw_collect (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
af5ca30d
NH
120
121 if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
34a79281 122 regcache->raw_collect (HPPA_SAR_REGNUM, regs + 32 * 4);
af5ca30d 123 if (regnum == -1 || regnum == HPPA_PCSQ_HEAD_REGNUM)
34a79281 124 regcache->raw_collect (HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
af5ca30d 125 if (regnum == -1 || regnum == HPPA_PCSQ_TAIL_REGNUM)
34a79281 126 regcache->raw_collect (HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
af5ca30d 127 if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
34a79281 128 regcache->raw_collect (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
af5ca30d 129 if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
34a79281 130 regcache->raw_collect (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
af5ca30d 131 if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
34a79281 132 regcache->raw_collect (HPPA_IPSW_REGNUM, regs);
af5ca30d 133 if (regnum == -1 || regnum == HPPA_SR4_REGNUM)
34a79281 134 regcache->raw_collect (HPPA_SR4_REGNUM, regs + 41 * 4);
af5ca30d 135 if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 1)
34a79281 136 regcache->raw_collect (HPPA_SR4_REGNUM + 1, regs + 37 * 4);
af5ca30d 137 if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 2)
34a79281 138 regcache->raw_collect (HPPA_SR4_REGNUM + 2, regs + 38 * 4);
af5ca30d 139 if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 3)
34a79281 140 regcache->raw_collect (HPPA_SR4_REGNUM + 3, regs + 39 * 4);
af5ca30d 141 if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 4)
34a79281 142 regcache->raw_collect (HPPA_SR4_REGNUM + 4, regs + 40 * 4);
af5ca30d
NH
143}
144
145/* Collect the floating-point registers from REGCACHE and store them
146 in FPREGS. */
147
148static void
149hppanbsd_collect_fpregset (struct regcache *regcache,
150 void *fpregs, int regnum)
151{
152 char *regs = fpregs;
153 int i;
154
155 for (i = HPPA_FP0_REGNUM; i <= HPPA_FP31R_REGNUM; i += 2, regs += 8)
156 {
157 if (regnum == -1 || regnum == i || regnum == i + 1)
158 {
34a79281
SM
159 regcache->raw_collect (i, regs);
160 regcache->raw_collect (i + 1, regs + 4);
af5ca30d
NH
161 }
162 }
163}
164\f
165
166/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
167 for all registers (including the floating-point registers). */
168
f6ac5f3d
PA
169void
170hppa_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
af5ca30d
NH
171
172{
e99b03dc 173 pid_t pid = regcache->ptid ().pid ();
4a90f062 174 int lwp = regcache->ptid ().lwp ();
10799020 175
af5ca30d
NH
176 if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
177 {
178 struct reg regs;
179
4a90f062 180 if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
af5ca30d
NH
181 perror_with_name (_("Couldn't get registers"));
182
183 hppanbsd_supply_gregset (regcache, &regs);
184 }
185
186 if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum))
187 {
188 struct fpreg fpregs;
189
4a90f062 190 if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
af5ca30d
NH
191 perror_with_name (_("Couldn't get floating point status"));
192
193 hppanbsd_supply_fpregset (regcache, &fpregs);
194 }
195}
196
197/* Store register REGNUM back into the inferior. If REGNUM is -1, do
198 this for all registers (including the floating-point registers). */
199
f6ac5f3d
PA
200void
201hppa_nbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
af5ca30d 202{
e99b03dc 203 pid_t pid = regcache->ptid ().pid ();
4a90f062 204 int lwp = regcache->ptid ().lwp ();
10799020 205
af5ca30d
NH
206 if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
207 {
208 struct reg regs;
209
4a90f062 210 if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
af5ca30d
NH
211 perror_with_name (_("Couldn't get registers"));
212
213 hppanbsd_collect_gregset (regcache, &regs, regnum);
214
4a90f062 215 if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
af5ca30d
NH
216 perror_with_name (_("Couldn't write registers"));
217 }
218
219 if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum))
220 {
221 struct fpreg fpregs;
222
4a90f062 223 if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
af5ca30d
NH
224 perror_with_name (_("Couldn't get floating point status"));
225
226 hppanbsd_collect_fpregset (regcache, &fpregs, regnum);
227
4a90f062 228 if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
af5ca30d
NH
229 perror_with_name (_("Couldn't write floating point status"));
230 }
231}
232
6c265988 233void _initialize_hppanbsd_nat ();
af5ca30d 234void
6c265988 235_initialize_hppanbsd_nat ()
af5ca30d 236{
d9f719f1 237 add_inf_child_target (&the_hppa_nbsd_nat_target);
af5ca30d 238}
This page took 1.00402 seconds and 4 git commands to generate.