gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / m68k-bsd-nat.c
CommitLineData
8f2d3ea0
MK
1/* Native-dependent code for Motorola 68000 BSD's.
2
b811d2c2 3 Copyright (C) 2004-2020 Free Software Foundation, Inc.
8f2d3ea0
MK
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
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
8f2d3ea0
MK
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
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
8f2d3ea0 19
f90280ca
KR
20/* We define this to get types like register_t. */
21#define _KERNTYPES
8f2d3ea0 22#include "defs.h"
cb162ff6 23#include "gdbcore.h"
8f2d3ea0
MK
24#include "inferior.h"
25#include "regcache.h"
26
8f2d3ea0
MK
27#include <sys/types.h>
28#include <sys/ptrace.h>
29#include <machine/reg.h>
30
31#include "m68k-tdep.h"
bcfca652 32#include "inf-ptrace.h"
01a80117 33#include "nbsd-nat.h"
8f2d3ea0 34
01a80117 35struct m68k_bsd_nat_target final : public nbsd_nat_target
f6ac5f3d
PA
36{
37 void fetch_registers (struct regcache *, int) override;
38 void store_registers (struct regcache *, int) override;
39};
40
41static m68k_bsd_nat_target the_m68k_bsd_nat_target;
42
8f2d3ea0
MK
43static int
44m68kbsd_gregset_supplies_p (int regnum)
45{
46 return (regnum >= M68K_D0_REGNUM && regnum <= M68K_PC_REGNUM);
47}
48
49static int
50m68kbsd_fpregset_supplies_p (int regnum)
51{
52 return (regnum >= M68K_FP0_REGNUM && regnum <= M68K_FPI_REGNUM);
53}
54
55/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
56
57static void
58m68kbsd_supply_gregset (struct regcache *regcache, const void *gregs)
59{
bc107784 60 const gdb_byte *regs = (const gdb_byte *) gregs;
8f2d3ea0
MK
61 int regnum;
62
63 for (regnum = M68K_D0_REGNUM; regnum <= M68K_PC_REGNUM; regnum++)
73e1c03f 64 regcache->raw_supply (regnum, regs + regnum * 4);
8f2d3ea0
MK
65}
66
67/* Supply the floating-point registers stored in FPREGS to REGCACHE. */
68
69static void
70m68kbsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
71{
ac7936df 72 struct gdbarch *gdbarch = regcache->arch ();
bc107784 73 const gdb_byte *regs = (const gdb_byte *) fpregs;
8f2d3ea0
MK
74 int regnum;
75
76 for (regnum = M68K_FP0_REGNUM; regnum <= M68K_FPI_REGNUM; regnum++)
73e1c03f
SM
77 regcache->raw_supply (regnum,
78 regs + m68kbsd_fpreg_offset (gdbarch, regnum));
8f2d3ea0
MK
79}
80
81/* Collect the general-purpose registers from REGCACHE and store them
82 in GREGS. */
83
84static void
85m68kbsd_collect_gregset (const struct regcache *regcache,
86 void *gregs, int regnum)
87{
bc107784 88 gdb_byte *regs = (gdb_byte *) gregs;
8f2d3ea0
MK
89 int i;
90
91 for (i = M68K_D0_REGNUM; i <= M68K_PC_REGNUM; i++)
92 {
93 if (regnum == -1 || regnum == i)
34a79281 94 regcache->raw_collect (i, regs + i * 4);
8f2d3ea0
MK
95 }
96}
97
98/* Collect the floating-point registers from REGCACHE and store them
99 in FPREGS. */
100
101static void
102m68kbsd_collect_fpregset (struct regcache *regcache,
103 void *fpregs, int regnum)
104{
ac7936df 105 struct gdbarch *gdbarch = regcache->arch ();
8f2d3ea0
MK
106 char *regs = fpregs;
107 int i;
108
109 for (i = M68K_FP0_REGNUM; i <= M68K_FPI_REGNUM; i++)
110 {
111 if (regnum == -1 || regnum == i)
34a79281 112 regcache->raw_collect (i, regs + m68kbsd_fpreg_offset (gdbarch, i));
8f2d3ea0
MK
113 }
114}
115\f
116
117/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
118 for all registers (including the floating-point registers). */
119
f6ac5f3d
PA
120void
121m68k_bsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
8f2d3ea0 122{
e99b03dc 123 pid_t pid = regcache->ptid ().pid ();
154151a6 124 int lwp = regcache->ptid ().lwp ();
bcc0c096 125
8f2d3ea0
MK
126 if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
127 {
128 struct reg regs;
129
154151a6 130 if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
e2e0b3e5 131 perror_with_name (_("Couldn't get registers"));
8f2d3ea0 132
56be3814 133 m68kbsd_supply_gregset (regcache, &regs);
8f2d3ea0
MK
134 }
135
136 if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum))
137 {
138 struct fpreg fpregs;
139
154151a6 140 if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
e2e0b3e5 141 perror_with_name (_("Couldn't get floating point status"));
8f2d3ea0 142
56be3814 143 m68kbsd_supply_fpregset (regcache, &fpregs);
8f2d3ea0
MK
144 }
145}
146
147/* Store register REGNUM back into the inferior. If REGNUM is -1, do
148 this for all registers (including the floating-point registers). */
149
f6ac5f3d
PA
150void
151m68k_bsd_nat_target::store_registers (struct regcache *regcache, int regnum)
8f2d3ea0 152{
e99b03dc 153 pid_t pid = regcache->ptid ().pid ();
154151a6 154 int lwp = regcache->ptid ().lwp ();
bcc0c096 155
8f2d3ea0
MK
156 if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
157 {
158 struct reg regs;
159
154151a6 160 if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
e2e0b3e5 161 perror_with_name (_("Couldn't get registers"));
8f2d3ea0 162
56be3814 163 m68kbsd_collect_gregset (regcache, &regs, regnum);
8f2d3ea0 164
154151a6 165 if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
e2e0b3e5 166 perror_with_name (_("Couldn't write registers"));
8f2d3ea0
MK
167 }
168
169 if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum))
170 {
171 struct fpreg fpregs;
172
154151a6 173 if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
e2e0b3e5 174 perror_with_name (_("Couldn't get floating point status"));
8f2d3ea0 175
56be3814 176 m68kbsd_collect_fpregset (regcache, &fpregs, regnum);
8f2d3ea0 177
154151a6 178 if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
e2e0b3e5 179 perror_with_name (_("Couldn't write floating point status"));
8f2d3ea0
MK
180 }
181}
cb162ff6
MK
182\f
183
184/* Support for debugging kernel virtual memory images. */
185
cb162ff6
MK
186#include <machine/pcb.h>
187
188#include "bsd-kvm.h"
189
190/* OpenBSD doesn't have these. */
191#ifndef PCB_REGS_FP
192#define PCB_REGS_FP 10
193#endif
194#ifndef PCB_REGS_SP
195#define PCB_REGS_SP 11
196#endif
197
198static int
199m68kbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
200{
201 int regnum, tmp;
202 int i = 0;
203
204 /* The following is true for NetBSD 1.6.2:
205
206 The pcb contains %d2...%d7, %a2...%a7 and %ps. This accounts for
207 all callee-saved registers. From this information we reconstruct
208 the register state as it would look when we just returned from
209 cpu_switch(). */
210
211 /* The stack pointer shouldn't be zero. */
212 if (pcb->pcb_regs[PCB_REGS_SP] == 0)
213 return 0;
214
215 for (regnum = M68K_D2_REGNUM; regnum <= M68K_D7_REGNUM; regnum++)
73e1c03f 216 regcache->raw_supply (regnum, &pcb->pcb_regs[i++]);
cb162ff6 217 for (regnum = M68K_A2_REGNUM; regnum <= M68K_SP_REGNUM; regnum++)
73e1c03f 218 regcache->raw_supply (regnum, &pcb->pcb_regs[i++]);
cb162ff6
MK
219
220 tmp = pcb->pcb_ps & 0xffff;
73e1c03f 221 regcache->raw_supply (M68K_PS_REGNUM, &tmp);
cb162ff6 222
bc107784 223 read_memory (pcb->pcb_regs[PCB_REGS_FP] + 4, (gdb_byte *) &tmp, sizeof tmp);
73e1c03f 224 regcache->raw_supply (M68K_PC_REGNUM, &tmp);
cb162ff6
MK
225
226 return 1;
227}
cb162ff6 228
6c265988 229void _initialize_m68kbsd_nat ();
cb162ff6 230void
6c265988 231_initialize_m68kbsd_nat ()
cb162ff6 232{
d9f719f1 233 add_inf_child_target (&the_m68k_bsd_nat_target);
abbc6945 234
cb162ff6
MK
235 /* Support debugging kernel virtual memory images. */
236 bsd_kvm_add_target (m68kbsd_supply_pcb);
237}
This page took 1.36253 seconds and 4 git commands to generate.