]> Git Repo - binutils.git/blob - gdb/ppc-netbsd-nat.c
gdb, gdbserver: make status_to_str display the signal name
[binutils.git] / gdb / ppc-netbsd-nat.c
1 /* Native-dependent code for NetBSD/powerpc.
2
3    Copyright (C) 2002-2021 Free Software Foundation, Inc.
4
5    Contributed by Wasabi Systems, Inc.
6
7    This file is part of GDB.
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21
22 /* We define this to get types like register_t.  */
23 #define _KERNTYPES
24 #include "defs.h"
25
26 #include <sys/types.h>
27 #include <sys/ptrace.h>
28 #include <machine/reg.h>
29 #include <machine/frame.h>
30 #include <machine/pcb.h>
31
32 #include "gdbcore.h"
33 #include "inferior.h"
34 #include "regcache.h"
35
36 #include "ppc-tdep.h"
37 #include "ppc-netbsd-tdep.h"
38 #include "bsd-kvm.h"
39 #include "inf-ptrace.h"
40 #include "netbsd-nat.h"
41
42 struct ppc_nbsd_nat_target final : public nbsd_nat_target
43 {
44   void fetch_registers (struct regcache *, int) override;
45   void store_registers (struct regcache *, int) override;
46 };
47
48 static ppc_nbsd_nat_target the_ppc_nbsd_nat_target;
49
50 /* Returns true if PT_GETREGS fetches this register.  */
51
52 static int
53 getregs_supplies (struct gdbarch *gdbarch, int regnum)
54 {
55   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
56
57   return ((regnum >= tdep->ppc_gp0_regnum
58            && regnum < tdep->ppc_gp0_regnum + ppc_num_gprs)
59           || regnum == tdep->ppc_lr_regnum
60           || regnum == tdep->ppc_cr_regnum
61           || regnum == tdep->ppc_xer_regnum
62           || regnum == tdep->ppc_ctr_regnum
63           || regnum == gdbarch_pc_regnum (gdbarch));
64 }
65
66 /* Like above, but for PT_GETFPREGS.  */
67
68 static int
69 getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
70 {
71   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
72
73   /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
74      point registers.  Traditionally, GDB's register set has still
75      listed the floating point registers for such machines, so this
76      code is harmless.  However, the new E500 port actually omits the
77      floating point registers entirely from the register set --- they
78      don't even have register numbers assigned to them.
79
80      It's not clear to me how best to update this code, so this assert
81      will alert the first person to encounter the NetBSD/E500
82      combination to the problem.  */
83   gdb_assert (ppc_floating_point_unit_p (gdbarch));
84
85   return ((regnum >= tdep->ppc_fp0_regnum
86            && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs)
87           || regnum == tdep->ppc_fpscr_regnum);
88 }
89
90 void
91 ppc_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
92 {
93   struct gdbarch *gdbarch = regcache->arch ();
94   pid_t pid = regcache->ptid ().pid ();
95   int lwp = regcache->ptid ().lwp ();
96
97   if (regnum == -1 || getregs_supplies (gdbarch, regnum))
98     {
99       struct reg regs;
100
101       if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
102         perror_with_name (_("Couldn't get registers"));
103
104       ppc_supply_gregset (&ppcnbsd_gregset, regcache,
105                           regnum, &regs, sizeof regs);
106     }
107
108   if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
109     {
110       struct fpreg fpregs;
111
112       if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
113         perror_with_name (_("Couldn't get FP registers"));
114
115       ppc_supply_fpregset (&ppcnbsd_fpregset, regcache,
116                            regnum, &fpregs, sizeof fpregs);
117     }
118 }
119
120 void
121 ppc_nbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
122 {
123   struct gdbarch *gdbarch = regcache->arch ();
124   pid_t pid = regcache->ptid ().pid ();
125   int lwp = regcache->ptid ().lwp ();
126
127   if (regnum == -1 || getregs_supplies (gdbarch, regnum))
128     {
129       struct reg regs;
130
131       if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
132         perror_with_name (_("Couldn't get registers"));
133
134       ppc_collect_gregset (&ppcnbsd_gregset, regcache,
135                            regnum, &regs, sizeof regs);
136
137       if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
138         perror_with_name (_("Couldn't write registers"));
139     }
140
141   if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
142     {
143       struct fpreg fpregs;
144
145       if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
146         perror_with_name (_("Couldn't get FP registers"));
147
148       ppc_collect_fpregset (&ppcnbsd_fpregset, regcache,
149                             regnum, &fpregs, sizeof fpregs);
150
151       if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
152         perror_with_name (_("Couldn't set FP registers"));
153     }
154 }
155
156 static int
157 ppcnbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
158 {
159   struct switchframe sf;
160   struct callframe cf;
161   struct gdbarch *gdbarch = regcache->arch ();
162   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
163   int i;
164
165   /* The stack pointer shouldn't be zero.  */
166   if (pcb->pcb_sp == 0)
167     return 0;
168
169   read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf);
170   regcache->raw_supply (tdep->ppc_cr_regnum, &sf.cr);
171   regcache->raw_supply (tdep->ppc_gp0_regnum + 2, &sf.fixreg2);
172   for (i = 0 ; i < 19 ; i++)
173     regcache->raw_supply (tdep->ppc_gp0_regnum + 13 + i, &sf.fixreg[i]);
174
175   read_memory(sf.sp, (gdb_byte *)&cf, sizeof(cf));
176   regcache->raw_supply (tdep->ppc_gp0_regnum + 30, &cf.r30);
177   regcache->raw_supply (tdep->ppc_gp0_regnum + 31, &cf.r31);
178   regcache->raw_supply (tdep->ppc_gp0_regnum + 1, &cf.sp);
179
180   read_memory(cf.sp, (gdb_byte *)&cf, sizeof(cf));
181   regcache->raw_supply (tdep->ppc_lr_regnum, &cf.lr);
182   regcache->raw_supply (gdbarch_pc_regnum (gdbarch), &cf.lr);
183
184   return 1;
185 }
186
187 void _initialize_ppcnbsd_nat ();
188 void
189 _initialize_ppcnbsd_nat ()
190 {
191   /* Support debugging kernel virtual memory images.  */
192   bsd_kvm_add_target (ppcnbsd_supply_pcb);
193
194   add_inf_child_target (&the_ppc_nbsd_nat_target);
195 }
This page took 0.037381 seconds and 4 git commands to generate.