xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/hppa-obsd-nat.c (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
1699b0f92Schristos /* Native-dependent code for OpenBSD/hppa.
2699b0f92Schristos 
3*6881a400Schristos    Copyright (C) 2004-2023 Free Software Foundation, Inc.
4699b0f92Schristos 
5699b0f92Schristos    This file is part of GDB.
6699b0f92Schristos 
7699b0f92Schristos    This program is free software; you can redistribute it and/or modify
8699b0f92Schristos    it under the terms of the GNU General Public License as published by
9699b0f92Schristos    the Free Software Foundation; either version 3 of the License, or
10699b0f92Schristos    (at your option) any later version.
11699b0f92Schristos 
12699b0f92Schristos    This program is distributed in the hope that it will be useful,
13699b0f92Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
14699b0f92Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15699b0f92Schristos    GNU General Public License for more details.
16699b0f92Schristos 
17699b0f92Schristos    You should have received a copy of the GNU General Public License
18699b0f92Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19699b0f92Schristos 
20699b0f92Schristos #include "defs.h"
21699b0f92Schristos #include "inferior.h"
22699b0f92Schristos #include "regcache.h"
23699b0f92Schristos #include "target.h"
24699b0f92Schristos 
25699b0f92Schristos #include <sys/types.h>
26699b0f92Schristos #include <sys/ptrace.h>
27699b0f92Schristos #include <machine/reg.h>
28699b0f92Schristos 
29699b0f92Schristos #include "hppa-tdep.h"
30699b0f92Schristos #include "inf-ptrace.h"
31699b0f92Schristos 
32699b0f92Schristos #include "obsd-nat.h"
33699b0f92Schristos 
347f2ac410Schristos struct hppa_obsd_nat_target final : public obsd_nat_target
357f2ac410Schristos {
367f2ac410Schristos   void fetch_registers (struct regcache *, int) override;
377f2ac410Schristos   void store_registers (struct regcache *, int) override;
387f2ac410Schristos };
397f2ac410Schristos 
407f2ac410Schristos static hppa_obsd_nat_target the_hppa_obsd_nat_target;
417f2ac410Schristos 
42699b0f92Schristos static int
43699b0f92Schristos hppaobsd_gregset_supplies_p (int regnum)
44699b0f92Schristos {
45699b0f92Schristos   return (regnum >= HPPA_R0_REGNUM && regnum <= HPPA_CR27_REGNUM);
46699b0f92Schristos }
47699b0f92Schristos 
48699b0f92Schristos static int
49699b0f92Schristos hppaobsd_fpregset_supplies_p (int regnum)
50699b0f92Schristos {
51699b0f92Schristos   return (regnum >= HPPA_FP0_REGNUM && regnum <= HPPA_FP31R_REGNUM);
52699b0f92Schristos }
53699b0f92Schristos 
54699b0f92Schristos /* Supply the general-purpose registers stored in GREGS to REGCACHE.  */
55699b0f92Schristos 
56699b0f92Schristos static void
57699b0f92Schristos hppaobsd_supply_gregset (struct regcache *regcache, const void *gregs)
58699b0f92Schristos {
59699b0f92Schristos   gdb_byte zero[4] = { 0 };
60699b0f92Schristos   const char *regs = gregs;
61699b0f92Schristos   int regnum;
62699b0f92Schristos 
637f2ac410Schristos   regcache->raw_supply (HPPA_R0_REGNUM, &zero);
64699b0f92Schristos   for (regnum = HPPA_R1_REGNUM; regnum <= HPPA_R31_REGNUM; regnum++)
657f2ac410Schristos     regcache->raw_supply (regnum, regs + regnum * 4);
66699b0f92Schristos 
67699b0f92Schristos   if (sizeof(struct reg) >= 46 * 4)
68699b0f92Schristos     {
697f2ac410Schristos       regcache->raw_supply (HPPA_IPSW_REGNUM, regs);
707f2ac410Schristos       regcache->raw_supply (HPPA_SAR_REGNUM, regs + 32 * 4);
717f2ac410Schristos       regcache->raw_supply (HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
727f2ac410Schristos       regcache->raw_supply (HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
737f2ac410Schristos       regcache->raw_supply (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
747f2ac410Schristos       regcache->raw_supply (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
757f2ac410Schristos       regcache->raw_supply (HPPA_SR0_REGNUM, regs + 37 * 4);
767f2ac410Schristos       regcache->raw_supply (HPPA_SR1_REGNUM, regs + 38 * 4);
777f2ac410Schristos       regcache->raw_supply (HPPA_SR2_REGNUM, regs + 39 * 4);
787f2ac410Schristos       regcache->raw_supply (HPPA_SR3_REGNUM, regs + 40 * 4);
797f2ac410Schristos       regcache->raw_supply (HPPA_SR4_REGNUM, regs + 41 * 4);
807f2ac410Schristos       regcache->raw_supply (HPPA_SR5_REGNUM, regs + 42 * 4);
817f2ac410Schristos       regcache->raw_supply (HPPA_SR6_REGNUM, regs + 43 * 4);
827f2ac410Schristos       regcache->raw_supply (HPPA_SR7_REGNUM, regs + 44 * 4);
837f2ac410Schristos       regcache->raw_supply (HPPA_CR26_REGNUM, regs + 45 * 4);
847f2ac410Schristos       regcache->raw_supply (HPPA_CR27_REGNUM, regs + 46 * 4);
85699b0f92Schristos     }
86699b0f92Schristos   else
87699b0f92Schristos     {
887f2ac410Schristos       regcache->raw_supply (HPPA_SAR_REGNUM, regs);
897f2ac410Schristos       regcache->raw_supply (HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
907f2ac410Schristos       regcache->raw_supply (HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
91699b0f92Schristos     }
92699b0f92Schristos }
93699b0f92Schristos 
94699b0f92Schristos /* Supply the floating-point registers stored in FPREGS to REGCACHE.  */
95699b0f92Schristos 
96699b0f92Schristos static void
97699b0f92Schristos hppaobsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
98699b0f92Schristos {
99699b0f92Schristos   const char *regs = fpregs;
100699b0f92Schristos   int regnum;
101699b0f92Schristos 
102699b0f92Schristos   for (regnum = HPPA_FP0_REGNUM; regnum <= HPPA_FP31R_REGNUM;
103699b0f92Schristos        regnum += 2, regs += 8)
104699b0f92Schristos     {
1057f2ac410Schristos       regcache->raw_supply (regnum, regs);
1067f2ac410Schristos       regcache->raw_supply (regnum + 1, regs + 4);
107699b0f92Schristos     }
108699b0f92Schristos }
109699b0f92Schristos 
110699b0f92Schristos /* Collect the general-purpose registers from REGCACHE and store them
111699b0f92Schristos    in GREGS.  */
112699b0f92Schristos 
113699b0f92Schristos static void
114699b0f92Schristos hppaobsd_collect_gregset (const struct regcache *regcache,
115699b0f92Schristos 			  void *gregs, int regnum)
116699b0f92Schristos {
117699b0f92Schristos   char *regs = gregs;
118699b0f92Schristos   int i;
119699b0f92Schristos 
120699b0f92Schristos   for (i = HPPA_R1_REGNUM; i <= HPPA_R31_REGNUM; i++)
121699b0f92Schristos     {
122699b0f92Schristos       if (regnum == -1 || regnum == i)
1237f2ac410Schristos 	regcache->raw_collect (i, regs + i * 4);
124699b0f92Schristos     }
125699b0f92Schristos 
126699b0f92Schristos   if (sizeof(struct reg) >= 46 * 4)
127699b0f92Schristos     {
128699b0f92Schristos       if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
1297f2ac410Schristos 	regcache->raw_collect (HPPA_IPSW_REGNUM, regs);
130699b0f92Schristos       if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
1317f2ac410Schristos 	regcache->raw_collect (HPPA_SAR_REGNUM, regs + 32 * 4);
132699b0f92Schristos       if (regnum == -1 || regnum == HPPA_PCSQ_HEAD_REGNUM)
1337f2ac410Schristos 	regcache->raw_collect (HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
134699b0f92Schristos       if (regnum == -1 || regnum == HPPA_PCSQ_TAIL_REGNUM)
1357f2ac410Schristos 	regcache->raw_collect (HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
136699b0f92Schristos       if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
1377f2ac410Schristos 	regcache->raw_collect (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
138699b0f92Schristos       if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
1397f2ac410Schristos 	regcache->raw_collect (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
140699b0f92Schristos       if (regnum == -1 || regnum == HPPA_SR0_REGNUM)
1417f2ac410Schristos 	regcache->raw_collect (HPPA_SR0_REGNUM, regs + 37 * 4);
142699b0f92Schristos       if (regnum == -1 || regnum == HPPA_SR1_REGNUM)
1437f2ac410Schristos 	regcache->raw_collect (HPPA_SR1_REGNUM, regs + 38 * 4);
144699b0f92Schristos       if (regnum == -1 || regnum == HPPA_SR2_REGNUM)
1457f2ac410Schristos 	regcache->raw_collect (HPPA_SR2_REGNUM, regs + 39 * 4);
146699b0f92Schristos       if (regnum == -1 || regnum == HPPA_SR3_REGNUM)
1477f2ac410Schristos 	regcache->raw_collect (HPPA_SR3_REGNUM, regs + 40 * 4);
148699b0f92Schristos       if (regnum == -1 || regnum == HPPA_SR4_REGNUM)
1497f2ac410Schristos 	regcache->raw_collect (HPPA_SR4_REGNUM, regs + 41 * 4);
150699b0f92Schristos       if (regnum == -1 || regnum == HPPA_SR5_REGNUM)
1517f2ac410Schristos 	regcache->raw_collect (HPPA_SR5_REGNUM, regs + 42 * 4);
152699b0f92Schristos       if (regnum == -1 || regnum == HPPA_SR6_REGNUM)
1537f2ac410Schristos 	regcache->raw_collect (HPPA_SR6_REGNUM, regs + 43 * 4);
154699b0f92Schristos       if (regnum == -1 || regnum == HPPA_SR7_REGNUM)
1557f2ac410Schristos 	regcache->raw_collect (HPPA_SR7_REGNUM, regs + 44 * 4);
156699b0f92Schristos       if (regnum == -1 || regnum == HPPA_CR26_REGNUM)
1577f2ac410Schristos 	regcache->raw_collect (HPPA_CR26_REGNUM, regs + 45 * 4);
158699b0f92Schristos       if (regnum == -1 || regnum == HPPA_CR27_REGNUM)
1597f2ac410Schristos 	regcache->raw_collect (HPPA_CR27_REGNUM, regs + 46 * 4);
160699b0f92Schristos     }
161699b0f92Schristos   else
162699b0f92Schristos     {
163699b0f92Schristos       if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
1647f2ac410Schristos 	regcache->raw_collect (HPPA_SAR_REGNUM, regs);
165699b0f92Schristos       if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
1667f2ac410Schristos 	regcache->raw_collect (HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
167699b0f92Schristos       if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
1687f2ac410Schristos 	regcache->raw_collect (HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
169699b0f92Schristos     }
170699b0f92Schristos }
171699b0f92Schristos 
172699b0f92Schristos /* Collect the floating-point registers from REGCACHE and store them
173699b0f92Schristos    in FPREGS.  */
174699b0f92Schristos 
175699b0f92Schristos static void
176699b0f92Schristos hppaobsd_collect_fpregset (struct regcache *regcache,
177699b0f92Schristos 			   void *fpregs, int regnum)
178699b0f92Schristos {
179699b0f92Schristos   char *regs = fpregs;
180699b0f92Schristos   int i;
181699b0f92Schristos 
182699b0f92Schristos   for (i = HPPA_FP0_REGNUM; i <= HPPA_FP31R_REGNUM; i += 2, regs += 8)
183699b0f92Schristos     {
184699b0f92Schristos       if (regnum == -1 || regnum == i || regnum == i + 1)
185699b0f92Schristos 	{
1867f2ac410Schristos 	  regcache->raw_collect (i, regs);
1877f2ac410Schristos 	  regcache->raw_collect (i + 1, regs + 4);
188699b0f92Schristos 	}
189699b0f92Schristos     }
190699b0f92Schristos }
191699b0f92Schristos 
192699b0f92Schristos 
193699b0f92Schristos /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
194699b0f92Schristos    for all registers (including the floating-point registers).  */
195699b0f92Schristos 
1967f2ac410Schristos void
1977f2ac410Schristos hppa_obsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
198699b0f92Schristos {
1997f2ac410Schristos   pid_t pid = regcache->ptid ().pid ();
200699b0f92Schristos 
201699b0f92Schristos   if (regnum == -1 || hppaobsd_gregset_supplies_p (regnum))
202699b0f92Schristos     {
203699b0f92Schristos       struct reg regs;
204699b0f92Schristos 
205699b0f92Schristos       if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
206699b0f92Schristos 	perror_with_name (_("Couldn't get registers"));
207699b0f92Schristos 
208699b0f92Schristos       hppaobsd_supply_gregset (regcache, &regs);
209699b0f92Schristos     }
210699b0f92Schristos 
211699b0f92Schristos   if (regnum == -1 || hppaobsd_fpregset_supplies_p (regnum))
212699b0f92Schristos     {
213699b0f92Schristos       struct fpreg fpregs;
214699b0f92Schristos 
215699b0f92Schristos       if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
216699b0f92Schristos 	perror_with_name (_("Couldn't get floating point status"));
217699b0f92Schristos 
218699b0f92Schristos       hppaobsd_supply_fpregset (regcache, &fpregs);
219699b0f92Schristos     }
220699b0f92Schristos }
221699b0f92Schristos 
222699b0f92Schristos /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
223699b0f92Schristos    this for all registers (including the floating-point registers).  */
224699b0f92Schristos 
2257f2ac410Schristos void
2267f2ac410Schristos hppa_obsd_nat_target::store_registers (struct regcache *regcache, int regnum)
227699b0f92Schristos {
228699b0f92Schristos   if (regnum == -1 || hppaobsd_gregset_supplies_p (regnum))
229699b0f92Schristos     {
230699b0f92Schristos       struct reg regs;
231699b0f92Schristos 
232699b0f92Schristos       if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
233699b0f92Schristos 	perror_with_name (_("Couldn't get registers"));
234699b0f92Schristos 
235699b0f92Schristos       hppaobsd_collect_gregset (regcache, &regs, regnum);
236699b0f92Schristos 
237699b0f92Schristos       if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
238699b0f92Schristos 	perror_with_name (_("Couldn't write registers"));
239699b0f92Schristos     }
240699b0f92Schristos 
241699b0f92Schristos   if (regnum == -1 || hppaobsd_fpregset_supplies_p (regnum))
242699b0f92Schristos     {
243699b0f92Schristos       struct fpreg fpregs;
244699b0f92Schristos 
245699b0f92Schristos       if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
246699b0f92Schristos 	perror_with_name (_("Couldn't get floating point status"));
247699b0f92Schristos 
248699b0f92Schristos       hppaobsd_collect_fpregset (regcache, &fpregs, regnum);
249699b0f92Schristos 
250699b0f92Schristos       if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
251699b0f92Schristos 	perror_with_name (_("Couldn't write floating point status"));
252699b0f92Schristos     }
253699b0f92Schristos }
254699b0f92Schristos 
2557d62b00eSchristos void _initialize_hppaobsd_nat ();
256699b0f92Schristos void
2577d62b00eSchristos _initialize_hppaobsd_nat ()
258699b0f92Schristos {
2597f2ac410Schristos   add_inf_child_target (&the_hppa_obsd_nat_target);
260699b0f92Schristos }
261