gdb/x86: Fix write out of mxcsr register for xsave targets
[deliverable/binutils-gdb.git] / gdb / hppa-obsd-nat.c
CommitLineData
2dcb2b1a 1/* Native-dependent code for OpenBSD/hppa.
0e56aeaf 2
e2882c85 3 Copyright (C) 2004-2018 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
cbb6aada 63 regcache_raw_supply (regcache, HPPA_R0_REGNUM, &zero);
0e56aeaf
MK
64 for (regnum = HPPA_R1_REGNUM; regnum <= HPPA_R31_REGNUM; regnum++)
65 regcache_raw_supply (regcache, regnum, regs + regnum * 4);
66
cbb6aada
MK
67 if (sizeof(struct reg) >= 46 * 4)
68 {
69 regcache_raw_supply (regcache, HPPA_IPSW_REGNUM, regs);
70 regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs + 32 * 4);
71 regcache_raw_supply (regcache, HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
72 regcache_raw_supply (regcache, HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
73 regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
74 regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
75 regcache_raw_supply (regcache, HPPA_SR0_REGNUM, regs + 37 * 4);
76 regcache_raw_supply (regcache, HPPA_SR1_REGNUM, regs + 38 * 4);
77 regcache_raw_supply (regcache, HPPA_SR2_REGNUM, regs + 39 * 4);
78 regcache_raw_supply (regcache, HPPA_SR3_REGNUM, regs + 40 * 4);
79 regcache_raw_supply (regcache, HPPA_SR4_REGNUM, regs + 41 * 4);
80 regcache_raw_supply (regcache, HPPA_SR5_REGNUM, regs + 42 * 4);
81 regcache_raw_supply (regcache, HPPA_SR6_REGNUM, regs + 43 * 4);
82 regcache_raw_supply (regcache, HPPA_SR7_REGNUM, regs + 44 * 4);
83 regcache_raw_supply (regcache, HPPA_CR26_REGNUM, regs + 45 * 4);
84 regcache_raw_supply (regcache, HPPA_CR27_REGNUM, regs + 46 * 4);
85 }
86 else
87 {
88 regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs);
89 regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
90 regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
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 {
105 regcache_raw_supply (regcache, regnum, regs);
106 regcache_raw_supply (regcache, regnum + 1, regs + 4);
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)
123 regcache_raw_collect (regcache, i, regs + i * 4);
124 }
125
cbb6aada
MK
126 if (sizeof(struct reg) >= 46 * 4)
127 {
128 if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
129 regcache_raw_collect (regcache, HPPA_IPSW_REGNUM, regs);
130 if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
131 regcache_raw_collect (regcache, HPPA_SAR_REGNUM, regs + 32 * 4);
132 if (regnum == -1 || regnum == HPPA_PCSQ_HEAD_REGNUM)
133 regcache_raw_collect (regcache, HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
134 if (regnum == -1 || regnum == HPPA_PCSQ_TAIL_REGNUM)
135 regcache_raw_collect (regcache, HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
136 if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
137 regcache_raw_collect (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
138 if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
139 regcache_raw_collect (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
140 if (regnum == -1 || regnum == HPPA_SR0_REGNUM)
141 regcache_raw_collect (regcache, HPPA_SR0_REGNUM, regs + 37 * 4);
142 if (regnum == -1 || regnum == HPPA_SR1_REGNUM)
143 regcache_raw_collect (regcache, HPPA_SR1_REGNUM, regs + 38 * 4);
144 if (regnum == -1 || regnum == HPPA_SR2_REGNUM)
145 regcache_raw_collect (regcache, HPPA_SR2_REGNUM, regs + 39 * 4);
146 if (regnum == -1 || regnum == HPPA_SR3_REGNUM)
147 regcache_raw_collect (regcache, HPPA_SR3_REGNUM, regs + 40 * 4);
148 if (regnum == -1 || regnum == HPPA_SR4_REGNUM)
149 regcache_raw_collect (regcache, HPPA_SR4_REGNUM, regs + 41 * 4);
150 if (regnum == -1 || regnum == HPPA_SR5_REGNUM)
151 regcache_raw_collect (regcache, HPPA_SR5_REGNUM, regs + 42 * 4);
152 if (regnum == -1 || regnum == HPPA_SR6_REGNUM)
153 regcache_raw_collect (regcache, HPPA_SR6_REGNUM, regs + 43 * 4);
154 if (regnum == -1 || regnum == HPPA_SR7_REGNUM)
155 regcache_raw_collect (regcache, HPPA_SR7_REGNUM, regs + 44 * 4);
156 if (regnum == -1 || regnum == HPPA_CR26_REGNUM)
157 regcache_raw_collect (regcache, HPPA_CR26_REGNUM, regs + 45 * 4);
158 if (regnum == -1 || regnum == HPPA_CR27_REGNUM)
159 regcache_raw_collect (regcache, HPPA_CR27_REGNUM, regs + 46 * 4);
160 }
161 else
162 {
163 if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
164 regcache_raw_collect (regcache, HPPA_SAR_REGNUM, regs);
165 if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
166 regcache_raw_collect (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
167 if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
168 regcache_raw_collect (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
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 {
186 regcache_raw_collect (regcache, i, regs);
187 regcache_raw_collect (regcache, i + 1, regs + 4);
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{
bbe1eef1
SM
199 pid_t pid = ptid_get_pid (regcache_get_ptid (regcache));
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
57cd0b54 255void
2dcb2b1a 256_initialize_hppaobsd_nat (void)
57cd0b54 257{
d9f719f1 258 add_inf_child_target (&the_hppa_obsd_nat_target);
57cd0b54 259}
This page took 1.072268 seconds and 4 git commands to generate.