hppa-netbsd-nat.c revision 1.1 1 1.1 christos /* Native-dependent code for NetBSD/hppa.
2 1.1 christos
3 1.1 christos Copyright (C) 2008-2023 Free Software Foundation, Inc.
4 1.1 christos
5 1.1 christos This file is part of GDB.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 1.1 christos
20 1.1 christos #include "defs.h"
21 1.1 christos #include "inferior.h"
22 1.1 christos #include "regcache.h"
23 1.1 christos
24 1.1 christos #include <sys/types.h>
25 1.1 christos #include <sys/ptrace.h>
26 1.1 christos #include <machine/reg.h>
27 1.1 christos
28 1.1 christos #include "hppa-tdep.h"
29 1.1 christos #include "inf-ptrace.h"
30 1.1 christos
31 1.1 christos #include "netbsd-nat.h"
32 1.1 christos
33 1.1 christos class hppa_nbsd_nat_target final : public nbsd_nat_target
34 1.1 christos {
35 1.1 christos void fetch_registers (struct regcache *, int) override;
36 1.1 christos void store_registers (struct regcache *, int) override;
37 1.1 christos };
38 1.1 christos
39 1.1 christos static hppa_nbsd_nat_target the_hppa_nbsd_nat_target;
40 1.1 christos
41 1.1 christos static int
42 1.1 christos hppanbsd_gregset_supplies_p (int regnum)
43 1.1 christos {
44 1.1 christos return ((regnum >= HPPA_R0_REGNUM && regnum <= HPPA_R31_REGNUM) ||
45 1.1 christos (regnum >= HPPA_SAR_REGNUM && regnum <= HPPA_PCSQ_TAIL_REGNUM) ||
46 1.1 christos regnum == HPPA_IPSW_REGNUM ||
47 1.1 christos (regnum >= HPPA_SR4_REGNUM && regnum <= HPPA_SR4_REGNUM + 5));
48 1.1 christos }
49 1.1 christos
50 1.1 christos static int
51 1.1 christos hppanbsd_fpregset_supplies_p (int regnum)
52 1.1 christos {
53 1.1 christos return (regnum >= HPPA_FP0_REGNUM && regnum <= HPPA_FP31R_REGNUM);
54 1.1 christos }
55 1.1 christos
56 1.1 christos /* Supply the general-purpose registers stored in GREGS to REGCACHE. */
57 1.1 christos
58 1.1 christos static void
59 1.1 christos hppanbsd_supply_gregset (struct regcache *regcache, const void *gregs)
60 1.1 christos {
61 1.1 christos const char *regs = (const char *)gregs;
62 1.1 christos int regnum;
63 1.1 christos
64 1.1 christos for (regnum = HPPA_R1_REGNUM; regnum <= HPPA_R31_REGNUM; regnum++)
65 1.1 christos regcache->raw_supply (regnum, regs + regnum * 4);
66 1.1 christos
67 1.1 christos regcache->raw_supply (HPPA_SAR_REGNUM, regs + 32 * 4);
68 1.1 christos regcache->raw_supply (HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
69 1.1 christos regcache->raw_supply (HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
70 1.1 christos regcache->raw_supply (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
71 1.1 christos regcache->raw_supply (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
72 1.1 christos regcache->raw_supply (HPPA_IPSW_REGNUM, regs);
73 1.1 christos regcache->raw_supply (HPPA_SR4_REGNUM, regs + 41 * 4);
74 1.1 christos regcache->raw_supply (HPPA_SR4_REGNUM + 1, regs + 37 * 4);
75 1.1 christos regcache->raw_supply (HPPA_SR4_REGNUM + 2, regs + 38 * 4);
76 1.1 christos regcache->raw_supply (HPPA_SR4_REGNUM + 3, regs + 39 * 4);
77 1.1 christos regcache->raw_supply (HPPA_SR4_REGNUM + 4, regs + 40 * 4);
78 1.1 christos }
79 1.1 christos
80 1.1 christos /* Supply the floating-point registers stored in FPREGS to REGCACHE. */
81 1.1 christos
82 1.1 christos static void
83 1.1 christos hppanbsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
84 1.1 christos {
85 1.1 christos const char *regs = (const char *)fpregs;
86 1.1 christos int regnum;
87 1.1 christos
88 1.1 christos for (regnum = HPPA_FP0_REGNUM; regnum <= HPPA_FP31R_REGNUM;
89 1.1 christos regnum += 2, regs += 8)
90 1.1 christos {
91 1.1 christos regcache->raw_supply (regnum, regs);
92 1.1 christos regcache->raw_supply (regnum + 1, regs + 4);
93 1.1 christos }
94 1.1 christos }
95 1.1 christos
96 1.1 christos /* Collect the general-purpose registers from REGCACHE and store them
97 1.1 christos in GREGS. */
98 1.1 christos
99 1.1 christos static void
100 1.1 christos hppanbsd_collect_gregset (const struct regcache *regcache,
101 1.1 christos void *gregs, int regnum)
102 1.1 christos {
103 1.1 christos char *regs = (char *)gregs;
104 1.1 christos int i;
105 1.1 christos
106 1.1 christos for (i = HPPA_R1_REGNUM; i <= HPPA_R31_REGNUM; i++)
107 1.1 christos {
108 1.1 christos if (regnum == -1 || regnum == i)
109 1.1 christos regcache->raw_collect (i, regs + i * 4);
110 1.1 christos }
111 1.1 christos
112 1.1 christos if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
113 1.1 christos regcache->raw_collect (HPPA_IPSW_REGNUM, regs);
114 1.1 christos if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
115 1.1 christos regcache->raw_collect (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
116 1.1 christos if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
117 1.1 christos regcache->raw_collect (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
118 1.1 christos
119 1.1 christos if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
120 1.1 christos regcache->raw_collect (HPPA_SAR_REGNUM, regs + 32 * 4);
121 1.1 christos if (regnum == -1 || regnum == HPPA_PCSQ_HEAD_REGNUM)
122 1.1 christos regcache->raw_collect (HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
123 1.1 christos if (regnum == -1 || regnum == HPPA_PCSQ_TAIL_REGNUM)
124 1.1 christos regcache->raw_collect (HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
125 1.1 christos if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
126 1.1 christos regcache->raw_collect (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
127 1.1 christos if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
128 1.1 christos regcache->raw_collect (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
129 1.1 christos if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
130 1.1 christos regcache->raw_collect (HPPA_IPSW_REGNUM, regs);
131 1.1 christos if (regnum == -1 || regnum == HPPA_SR4_REGNUM)
132 1.1 christos regcache->raw_collect (HPPA_SR4_REGNUM, regs + 41 * 4);
133 1.1 christos if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 1)
134 1.1 christos regcache->raw_collect (HPPA_SR4_REGNUM + 1, regs + 37 * 4);
135 1.1 christos if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 2)
136 1.1 christos regcache->raw_collect (HPPA_SR4_REGNUM + 2, regs + 38 * 4);
137 1.1 christos if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 3)
138 1.1 christos regcache->raw_collect (HPPA_SR4_REGNUM + 3, regs + 39 * 4);
139 1.1 christos if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 4)
140 1.1 christos regcache->raw_collect (HPPA_SR4_REGNUM + 4, regs + 40 * 4);
141 1.1 christos }
142 1.1 christos
143 1.1 christos /* Collect the floating-point registers from REGCACHE and store them
144 1.1 christos in FPREGS. */
145 1.1 christos
146 1.1 christos static void
147 1.1 christos hppanbsd_collect_fpregset (const struct regcache *regcache,
148 1.1 christos void *fpregs, int regnum)
149 1.1 christos {
150 1.1 christos char *regs = (char *)fpregs;
151 1.1 christos int i;
152 1.1 christos
153 1.1 christos for (i = HPPA_FP0_REGNUM; i <= HPPA_FP31R_REGNUM; i += 2, regs += 8)
154 1.1 christos {
155 1.1 christos if (regnum == -1 || regnum == i || regnum == i + 1)
156 1.1 christos {
157 1.1 christos regcache->raw_collect (i, regs);
158 1.1 christos regcache->raw_collect (i + 1, regs + 4);
159 1.1 christos }
160 1.1 christos }
161 1.1 christos }
162 1.1 christos
163 1.1 christos
165 1.1 christos /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
166 1.1 christos for all registers (including the floating-point registers). */
167 1.1 christos
168 1.1 christos void
169 1.1 christos hppa_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
170 1.1 christos
171 1.1 christos {
172 1.1 christos pid_t pid = regcache->ptid ().pid ();
173 1.1 christos int lwp = regcache->ptid ().lwp ();
174 1.1 christos
175 1.1 christos if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
176 1.1 christos {
177 1.1 christos struct reg regs;
178 1.1 christos
179 1.1 christos if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1)
180 1.1 christos perror_with_name (_("Couldn't get registers"));
181 1.1 christos
182 1.1 christos hppanbsd_supply_gregset (regcache, ®s);
183 1.1 christos }
184 1.1 christos
185 1.1 christos if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum))
186 1.1 christos {
187 1.1 christos struct fpreg fpregs;
188 1.1 christos
189 1.1 christos if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
190 1.1 christos perror_with_name (_("Couldn't get floating point status"));
191 1.1 christos
192 1.1 christos hppanbsd_supply_fpregset (regcache, &fpregs);
193 1.1 christos }
194 1.1 christos }
195 1.1 christos
196 1.1 christos /* Store register REGNUM back into the inferior. If REGNUM is -1, do
197 1.1 christos this for all registers (including the floating-point registers). */
198 1.1 christos
199 1.1 christos void
200 1.1 christos hppa_nbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
201 1.1 christos {
202 1.1 christos pid_t pid = regcache->ptid ().pid ();
203 1.1 christos int lwp = regcache->ptid ().lwp ();
204 1.1 christos
205 1.1 christos if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
206 1.1 christos {
207 1.1 christos struct reg regs;
208 1.1 christos
209 1.1 christos if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1)
210 1.1 christos perror_with_name (_("Couldn't get registers"));
211 1.1 christos
212 1.1 christos hppanbsd_collect_gregset (regcache, ®s, regnum);
213 1.1 christos
214 1.1 christos if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1)
215 1.1 christos perror_with_name (_("Couldn't write registers"));
216 1.1 christos }
217 1.1 christos
218 1.1 christos if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum))
219 1.1 christos {
220 1.1 christos struct fpreg fpregs;
221 1.1 christos
222 1.1 christos if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
223 1.1 christos perror_with_name (_("Couldn't get floating point status"));
224 1.1 christos
225 1.1 christos hppanbsd_collect_fpregset (regcache, &fpregs, regnum);
226 1.1 christos
227 1.1 christos if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
228 1.1 christos perror_with_name (_("Couldn't write floating point status"));
229 1.1 christos }
230 1.1 christos }
231 1.1 christos
232 1.1 christos void _initialize_hppanbsd_nat ();
233 1.1 christos void
234 1.1 christos _initialize_hppanbsd_nat ()
235 1.1 christos {
236 1.1 christos add_inf_child_target (&the_hppa_nbsd_nat_target);
237 }
238