xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/alpha-bsd-nat.c (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
1 /* Native-dependent code for Alpha BSD's.
2 
3    Copyright (C) 2000-2023 Free Software Foundation, Inc.
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
9    the Free Software Foundation; either version 3 of the License, or
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
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 /* We define this to get types like register_t.  */
21 #include "defs.h"
22 #include "inferior.h"
23 #include "regcache.h"
24 
25 #include "alpha-tdep.h"
26 #include "alpha-bsd-tdep.h"
27 #include "inf-ptrace.h"
28 #include "netbsd-nat.h"
29 
30 #include <sys/types.h>
31 #include <sys/ptrace.h>
32 #include <machine/reg.h>
33 
34 struct alpha_bsd_nat_target final : public nbsd_nat_target
35 {
36   void fetch_registers (struct regcache *, int) override;
37   void store_registers (struct regcache *, int) override;
38 };
39 
40 static alpha_bsd_nat_target the_alpha_bsd_nat_target;
41 
42 /* Determine if PT_GETREGS fetches this register.  */
43 
44 static int
45 getregs_supplies (int regno)
46 {
47   return ((regno >= ALPHA_V0_REGNUM && regno <= ALPHA_ZERO_REGNUM)
48 	  || regno >= ALPHA_PC_REGNUM);
49 }
50 
51 /* Fetch register REGNO from the inferior.  If REGNO is -1, do this
52    for all registers (including the floating point registers).  */
53 
54 void
55 alpha_bsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
56 {
57   int lwp = regcache->ptid ().lwp ();
58 
59   if (regno == -1 || getregs_supplies (regno))
60     {
61       struct reg gregs;
62 
63       if (ptrace (PT_GETREGS, regcache->ptid ().pid (),
64 		  (PTRACE_TYPE_ARG3) &gregs, lwp) == -1)
65 	perror_with_name (_("Couldn't get registers"));
66 
67       alphabsd_supply_reg (regcache, (char *) &gregs, regno);
68       if (regno != -1)
69 	return;
70     }
71 
72   if (regno == -1
73       || regno >= gdbarch_fp0_regnum (regcache->arch ()))
74     {
75       struct fpreg fpregs;
76 
77       if (ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
78 		  (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
79 	perror_with_name (_("Couldn't get floating point status"));
80 
81       alphabsd_supply_fpreg (regcache, (char *) &fpregs, regno);
82     }
83 }
84 
85 /* Store register REGNO back into the inferior.  If REGNO is -1, do
86    this for all registers (including the floating point registers).  */
87 
88 void
89 alpha_bsd_nat_target::store_registers (struct regcache *regcache, int regno)
90 {
91   int lwp = regcache->ptid ().lwp ();
92 
93   if (regno == -1 || getregs_supplies (regno))
94     {
95       struct reg gregs;
96       if (ptrace (PT_GETREGS, regcache->ptid ().pid (),
97 		  (PTRACE_TYPE_ARG3) &gregs, lwp) == -1)
98 	perror_with_name (_("Couldn't get registers"));
99 
100       alphabsd_fill_reg (regcache, (char *) &gregs, regno);
101 
102       if (ptrace (PT_SETREGS, regcache->ptid ().pid (),
103 		  (PTRACE_TYPE_ARG3) &gregs, lwp) == -1)
104 	perror_with_name (_("Couldn't write registers"));
105 
106       if (regno != -1)
107 	return;
108     }
109 
110   if (regno == -1
111       || regno >= gdbarch_fp0_regnum (regcache->arch ()))
112     {
113       struct fpreg fpregs;
114 
115       if (ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
116 		  (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
117 	perror_with_name (_("Couldn't get floating point status"));
118 
119       alphabsd_fill_fpreg (regcache, (char *) &fpregs, regno);
120 
121       if (ptrace (PT_SETFPREGS, regcache->ptid ().pid (),
122 		  (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
123 	perror_with_name (_("Couldn't write floating point status"));
124     }
125 }
126 
127 
128 /* Support for debugging kernel virtual memory images.  */
129 
130 #include <sys/signal.h>
131 #include <machine/pcb.h>
132 
133 #include "bsd-kvm.h"
134 
135 static int
136 alphabsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
137 {
138   int regnum;
139 
140   /* The following is true for OpenBSD 3.9:
141 
142      The pcb contains the register state at the context switch inside
143      cpu_switch().  */
144 
145   /* The stack pointer shouldn't be zero.  */
146   if (pcb->pcb_hw.apcb_ksp == 0)
147     return 0;
148 
149   regcache->raw_supply (ALPHA_SP_REGNUM, &pcb->pcb_hw.apcb_ksp);
150 
151   for (regnum = ALPHA_S0_REGNUM; regnum < ALPHA_A0_REGNUM; regnum++)
152     regcache->raw_supply (regnum, &pcb->pcb_context[regnum - ALPHA_S0_REGNUM]);
153   regcache->raw_supply (ALPHA_RA_REGNUM, &pcb->pcb_context[7]);
154 
155   return 1;
156 }
157 
158 
159 void _initialize_alphabsd_nat ();
160 void
161 _initialize_alphabsd_nat ()
162 {
163   add_inf_child_target (&the_alpha_bsd_nat_target);
164 
165   /* Support debugging kernel virtual memory images.  */
166   bsd_kvm_add_target (alphabsd_supply_pcb);
167 }
168