GDB: Add ChangeLog entry inadvertently omitted from commit.
[external/binutils.git] / gdb / ppc-nbsd-nat.c
1 /* Native-dependent code for NetBSD/powerpc.
2
3    Copyright (C) 2002-2018 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 #include "defs.h"
23
24 #include <sys/types.h>
25 #include <sys/ptrace.h>
26 #include <machine/reg.h>
27 #include <machine/frame.h>
28 #include <machine/pcb.h>
29
30 #include "gdbcore.h"
31 #include "inferior.h"
32 #include "regcache.h"
33
34 #include "ppc-tdep.h"
35 #include "ppc-nbsd-tdep.h"
36 #include "bsd-kvm.h"
37 #include "inf-ptrace.h"
38
39 struct ppc_nbsd_nat_target final : public inf_ptrace_target
40 {
41   void fetch_registers (struct regcache *, int) override;
42   void store_registers (struct regcache *, int) override;
43 };
44
45 static ppc_nbsd_nat_target the_ppc_nbsd_nat_target;
46
47 /* Returns true if PT_GETREGS fetches this register.  */
48
49 static int
50 getregs_supplies (struct gdbarch *gdbarch, int regnum)
51 {
52   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
53
54   return ((regnum >= tdep->ppc_gp0_regnum
55            && regnum < tdep->ppc_gp0_regnum + ppc_num_gprs)
56           || regnum == tdep->ppc_lr_regnum
57           || regnum == tdep->ppc_cr_regnum
58           || regnum == tdep->ppc_xer_regnum
59           || regnum == tdep->ppc_ctr_regnum
60           || regnum == gdbarch_pc_regnum (gdbarch));
61 }
62
63 /* Like above, but for PT_GETFPREGS.  */
64
65 static int
66 getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
67 {
68   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
69
70   /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
71      point registers.  Traditionally, GDB's register set has still
72      listed the floating point registers for such machines, so this
73      code is harmless.  However, the new E500 port actually omits the
74      floating point registers entirely from the register set --- they
75      don't even have register numbers assigned to them.
76
77      It's not clear to me how best to update this code, so this assert
78      will alert the first person to encounter the NetBSD/E500
79      combination to the problem.  */
80   gdb_assert (ppc_floating_point_unit_p (gdbarch));
81
82   return ((regnum >= tdep->ppc_fp0_regnum
83            && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs)
84           || regnum == tdep->ppc_fpscr_regnum);
85 }
86
87 void
88 ppc_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
89 {
90   struct gdbarch *gdbarch = regcache->arch ();
91   pid_t pid = regcache->ptid ().pid ();
92
93   if (regnum == -1 || getregs_supplies (gdbarch, regnum))
94     {
95       struct reg regs;
96
97       if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
98         perror_with_name (_("Couldn't get registers"));
99
100       ppc_supply_gregset (&ppcnbsd_gregset, regcache,
101                           regnum, &regs, sizeof regs);
102     }
103
104   if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
105     {
106       struct fpreg fpregs;
107
108       if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
109         perror_with_name (_("Couldn't get FP registers"));
110
111       ppc_supply_fpregset (&ppcnbsd_fpregset, regcache,
112                            regnum, &fpregs, sizeof fpregs);
113     }
114 }
115
116 void
117 ppc_nbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
118 {
119   struct gdbarch *gdbarch = regcache->arch ();
120   pid_t pid = regcache->ptid ().pid ();
121
122   if (regnum == -1 || getregs_supplies (gdbarch, regnum))
123     {
124       struct reg regs;
125
126       if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
127         perror_with_name (_("Couldn't get registers"));
128
129       ppc_collect_gregset (&ppcnbsd_gregset, regcache,
130                            regnum, &regs, sizeof regs);
131
132       if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
133         perror_with_name (_("Couldn't write registers"));
134     }
135
136   if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
137     {
138       struct fpreg fpregs;
139
140       if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
141         perror_with_name (_("Couldn't get FP registers"));
142
143       ppc_collect_fpregset (&ppcnbsd_fpregset, regcache,
144                             regnum, &fpregs, sizeof fpregs);
145
146       if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
147         perror_with_name (_("Couldn't set FP registers"));
148     }
149 }
150
151 static int
152 ppcnbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
153 {
154   struct switchframe sf;
155   struct callframe cf;
156   struct gdbarch *gdbarch = regcache->arch ();
157   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
158   int i;
159
160   /* The stack pointer shouldn't be zero.  */
161   if (pcb->pcb_sp == 0)
162     return 0;
163
164   read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf);
165   regcache->raw_supply (tdep->ppc_cr_regnum, &sf.cr);
166   regcache->raw_supply (tdep->ppc_gp0_regnum + 2, &sf.fixreg2);
167   for (i = 0 ; i < 19 ; i++)
168     regcache->raw_supply (tdep->ppc_gp0_regnum + 13 + i, &sf.fixreg[i]);
169
170   read_memory(sf.sp, (gdb_byte *)&cf, sizeof(cf));
171   regcache->raw_supply (tdep->ppc_gp0_regnum + 30, &cf.r30);
172   regcache->raw_supply (tdep->ppc_gp0_regnum + 31, &cf.r31);
173   regcache->raw_supply (tdep->ppc_gp0_regnum + 1, &cf.sp);
174
175   read_memory(cf.sp, (gdb_byte *)&cf, sizeof(cf));
176   regcache->raw_supply (tdep->ppc_lr_regnum, &cf.lr);
177   regcache->raw_supply (gdbarch_pc_regnum (gdbarch), &cf.lr);
178
179   return 1;
180 }
181
182 void
183 _initialize_ppcnbsd_nat (void)
184 {
185   /* Support debugging kernel virtual memory images.  */
186   bsd_kvm_add_target (ppcnbsd_supply_pcb);
187
188   add_inf_child_target (&the_ppc_nbsd_nat_target);
189 }