xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/alpha-bsd-nat.c (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
1699b0f92Schristos /* Native-dependent code for Alpha BSD's.
2699b0f92Schristos 
3*6881a400Schristos    Copyright (C) 2000-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 
207d62b00eSchristos /* We define this to get types like register_t.  */
21699b0f92Schristos #include "defs.h"
22699b0f92Schristos #include "inferior.h"
23699b0f92Schristos #include "regcache.h"
24699b0f92Schristos 
25699b0f92Schristos #include "alpha-tdep.h"
26699b0f92Schristos #include "alpha-bsd-tdep.h"
27699b0f92Schristos #include "inf-ptrace.h"
28*6881a400Schristos #include "netbsd-nat.h"
29699b0f92Schristos 
30699b0f92Schristos #include <sys/types.h>
31699b0f92Schristos #include <sys/ptrace.h>
32699b0f92Schristos #include <machine/reg.h>
33699b0f92Schristos 
347f2ac410Schristos struct alpha_bsd_nat_target final : public nbsd_nat_target
35699b0f92Schristos {
367f2ac410Schristos   void fetch_registers (struct regcache *, int) override;
377f2ac410Schristos   void store_registers (struct regcache *, int) override;
387f2ac410Schristos };
39699b0f92Schristos 
407f2ac410Schristos static alpha_bsd_nat_target the_alpha_bsd_nat_target;
41699b0f92Schristos 
42699b0f92Schristos /* Determine if PT_GETREGS fetches this register.  */
43699b0f92Schristos 
44699b0f92Schristos static int
45699b0f92Schristos getregs_supplies (int regno)
46699b0f92Schristos {
47699b0f92Schristos   return ((regno >= ALPHA_V0_REGNUM && regno <= ALPHA_ZERO_REGNUM)
48699b0f92Schristos 	  || regno >= ALPHA_PC_REGNUM);
49699b0f92Schristos }
50699b0f92Schristos 
51699b0f92Schristos /* Fetch register REGNO from the inferior.  If REGNO is -1, do this
52699b0f92Schristos    for all registers (including the floating point registers).  */
53699b0f92Schristos 
547f2ac410Schristos void
557f2ac410Schristos alpha_bsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
56699b0f92Schristos {
577d62b00eSchristos   int lwp = regcache->ptid ().lwp ();
587f2ac410Schristos 
59699b0f92Schristos   if (regno == -1 || getregs_supplies (regno))
60699b0f92Schristos     {
61699b0f92Schristos       struct reg gregs;
62699b0f92Schristos 
637d62b00eSchristos       if (ptrace (PT_GETREGS, regcache->ptid ().pid (),
647d62b00eSchristos 		  (PTRACE_TYPE_ARG3) &gregs, lwp) == -1)
65699b0f92Schristos 	perror_with_name (_("Couldn't get registers"));
66699b0f92Schristos 
67699b0f92Schristos       alphabsd_supply_reg (regcache, (char *) &gregs, regno);
68699b0f92Schristos       if (regno != -1)
69699b0f92Schristos 	return;
70699b0f92Schristos     }
71699b0f92Schristos 
72699b0f92Schristos   if (regno == -1
737f2ac410Schristos       || regno >= gdbarch_fp0_regnum (regcache->arch ()))
74699b0f92Schristos     {
75699b0f92Schristos       struct fpreg fpregs;
76699b0f92Schristos 
777d62b00eSchristos       if (ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
787d62b00eSchristos 		  (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
79699b0f92Schristos 	perror_with_name (_("Couldn't get floating point status"));
80699b0f92Schristos 
81699b0f92Schristos       alphabsd_supply_fpreg (regcache, (char *) &fpregs, regno);
82699b0f92Schristos     }
83699b0f92Schristos }
84699b0f92Schristos 
85699b0f92Schristos /* Store register REGNO back into the inferior.  If REGNO is -1, do
86699b0f92Schristos    this for all registers (including the floating point registers).  */
87699b0f92Schristos 
887f2ac410Schristos void
897f2ac410Schristos alpha_bsd_nat_target::store_registers (struct regcache *regcache, int regno)
90699b0f92Schristos {
917d62b00eSchristos   int lwp = regcache->ptid ().lwp ();
927f2ac410Schristos 
93699b0f92Schristos   if (regno == -1 || getregs_supplies (regno))
94699b0f92Schristos     {
95699b0f92Schristos       struct reg gregs;
967d62b00eSchristos       if (ptrace (PT_GETREGS, regcache->ptid ().pid (),
977f2ac410Schristos 		  (PTRACE_TYPE_ARG3) &gregs, lwp) == -1)
98699b0f92Schristos 	perror_with_name (_("Couldn't get registers"));
99699b0f92Schristos 
100699b0f92Schristos       alphabsd_fill_reg (regcache, (char *) &gregs, regno);
101699b0f92Schristos 
1027d62b00eSchristos       if (ptrace (PT_SETREGS, regcache->ptid ().pid (),
1037d62b00eSchristos 		  (PTRACE_TYPE_ARG3) &gregs, lwp) == -1)
104699b0f92Schristos 	perror_with_name (_("Couldn't write registers"));
105699b0f92Schristos 
106699b0f92Schristos       if (regno != -1)
107699b0f92Schristos 	return;
108699b0f92Schristos     }
109699b0f92Schristos 
110699b0f92Schristos   if (regno == -1
1117f2ac410Schristos       || regno >= gdbarch_fp0_regnum (regcache->arch ()))
112699b0f92Schristos     {
113699b0f92Schristos       struct fpreg fpregs;
114699b0f92Schristos 
1157d62b00eSchristos       if (ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
1167d62b00eSchristos 		  (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
117699b0f92Schristos 	perror_with_name (_("Couldn't get floating point status"));
118699b0f92Schristos 
119699b0f92Schristos       alphabsd_fill_fpreg (regcache, (char *) &fpregs, regno);
120699b0f92Schristos 
1217d62b00eSchristos       if (ptrace (PT_SETFPREGS, regcache->ptid ().pid (),
1227f2ac410Schristos 		  (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
123699b0f92Schristos 	perror_with_name (_("Couldn't write floating point status"));
124699b0f92Schristos     }
125699b0f92Schristos }
126699b0f92Schristos 
127699b0f92Schristos 
128699b0f92Schristos /* Support for debugging kernel virtual memory images.  */
129699b0f92Schristos 
130699b0f92Schristos #include <sys/signal.h>
131699b0f92Schristos #include <machine/pcb.h>
132699b0f92Schristos 
133699b0f92Schristos #include "bsd-kvm.h"
134699b0f92Schristos 
135699b0f92Schristos static int
136699b0f92Schristos alphabsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
137699b0f92Schristos {
138699b0f92Schristos   int regnum;
139699b0f92Schristos 
140699b0f92Schristos   /* The following is true for OpenBSD 3.9:
141699b0f92Schristos 
142699b0f92Schristos      The pcb contains the register state at the context switch inside
143699b0f92Schristos      cpu_switch().  */
144699b0f92Schristos 
145699b0f92Schristos   /* The stack pointer shouldn't be zero.  */
146699b0f92Schristos   if (pcb->pcb_hw.apcb_ksp == 0)
147699b0f92Schristos     return 0;
148699b0f92Schristos 
1497f2ac410Schristos   regcache->raw_supply (ALPHA_SP_REGNUM, &pcb->pcb_hw.apcb_ksp);
150699b0f92Schristos 
151699b0f92Schristos   for (regnum = ALPHA_S0_REGNUM; regnum < ALPHA_A0_REGNUM; regnum++)
1527f2ac410Schristos     regcache->raw_supply (regnum, &pcb->pcb_context[regnum - ALPHA_S0_REGNUM]);
1537f2ac410Schristos   regcache->raw_supply (ALPHA_RA_REGNUM, &pcb->pcb_context[7]);
154699b0f92Schristos 
155699b0f92Schristos   return 1;
156699b0f92Schristos }
157699b0f92Schristos 
158699b0f92Schristos 
1597d62b00eSchristos void _initialize_alphabsd_nat ();
160699b0f92Schristos void
1617d62b00eSchristos _initialize_alphabsd_nat ()
162699b0f92Schristos {
1637f2ac410Schristos   add_inf_child_target (&the_alpha_bsd_nat_target);
164699b0f92Schristos 
165699b0f92Schristos   /* Support debugging kernel virtual memory images.  */
166699b0f92Schristos   bsd_kvm_add_target (alphabsd_supply_pcb);
167699b0f92Schristos }
168