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