]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/m68kbsd-nat.c
Update Copyright year range in all files maintained by GDB.
[thirdparty/binutils-gdb.git] / gdb / m68kbsd-nat.c
CommitLineData
8f2d3ea0
MK
1/* Native-dependent code for Motorola 68000 BSD's.
2
ecd75fc8 3 Copyright (C) 2004-2014 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
MK
19
20#include "defs.h"
cb162ff6 21#include "gdbcore.h"
8f2d3ea0
MK
22#include "inferior.h"
23#include "regcache.h"
24
25#include "gdb_assert.h"
26#include <sys/types.h>
27#include <sys/ptrace.h>
28#include <machine/reg.h>
29
30#include "m68k-tdep.h"
bcfca652 31#include "inf-ptrace.h"
8f2d3ea0
MK
32
33static int
34m68kbsd_gregset_supplies_p (int regnum)
35{
36 return (regnum >= M68K_D0_REGNUM && regnum <= M68K_PC_REGNUM);
37}
38
39static int
40m68kbsd_fpregset_supplies_p (int regnum)
41{
42 return (regnum >= M68K_FP0_REGNUM && regnum <= M68K_FPI_REGNUM);
43}
44
45/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
46
47static void
48m68kbsd_supply_gregset (struct regcache *regcache, const void *gregs)
49{
50 const char *regs = gregs;
51 int regnum;
52
53 for (regnum = M68K_D0_REGNUM; regnum <= M68K_PC_REGNUM; regnum++)
54 regcache_raw_supply (regcache, regnum, regs + regnum * 4);
55}
56
57/* Supply the floating-point registers stored in FPREGS to REGCACHE. */
58
59static void
60m68kbsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
61{
6ba38425 62 struct gdbarch *gdbarch = get_regcache_arch (regcache);
8f2d3ea0
MK
63 const char *regs = fpregs;
64 int regnum;
65
66 for (regnum = M68K_FP0_REGNUM; regnum <= M68K_FPI_REGNUM; regnum++)
67 regcache_raw_supply (regcache, regnum,
6ba38425 68 regs + m68kbsd_fpreg_offset (gdbarch, regnum));
8f2d3ea0
MK
69}
70
71/* Collect the general-purpose registers from REGCACHE and store them
72 in GREGS. */
73
74static void
75m68kbsd_collect_gregset (const struct regcache *regcache,
76 void *gregs, int regnum)
77{
78 char *regs = gregs;
79 int i;
80
81 for (i = M68K_D0_REGNUM; i <= M68K_PC_REGNUM; i++)
82 {
83 if (regnum == -1 || regnum == i)
5df97fde 84 regcache_raw_collect (regcache, i, regs + i * 4);
8f2d3ea0
MK
85 }
86}
87
88/* Collect the floating-point registers from REGCACHE and store them
89 in FPREGS. */
90
91static void
92m68kbsd_collect_fpregset (struct regcache *regcache,
93 void *fpregs, int regnum)
94{
6ba38425 95 struct gdbarch *gdbarch = get_regcache_arch (regcache);
8f2d3ea0
MK
96 char *regs = fpregs;
97 int i;
98
99 for (i = M68K_FP0_REGNUM; i <= M68K_FPI_REGNUM; i++)
100 {
101 if (regnum == -1 || regnum == i)
6ba38425
UW
102 regcache_raw_collect (regcache, i,
103 regs + m68kbsd_fpreg_offset (gdbarch, i));
8f2d3ea0
MK
104 }
105}
106\f
107
108/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
109 for all registers (including the floating-point registers). */
110
abbc6945 111static void
28439f5e
PA
112m68kbsd_fetch_inferior_registers (struct target_ops *ops,
113 struct regcache *regcache, int regnum)
8f2d3ea0
MK
114{
115 if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
116 {
117 struct reg regs;
118
dfd4cc63 119 if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
9f8e0089 120 (PTRACE_TYPE_ARG3) &regs, 0) == -1)
e2e0b3e5 121 perror_with_name (_("Couldn't get registers"));
8f2d3ea0 122
56be3814 123 m68kbsd_supply_gregset (regcache, &regs);
8f2d3ea0
MK
124 }
125
126 if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum))
127 {
128 struct fpreg fpregs;
129
dfd4cc63 130 if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
9f8e0089 131 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
e2e0b3e5 132 perror_with_name (_("Couldn't get floating point status"));
8f2d3ea0 133
56be3814 134 m68kbsd_supply_fpregset (regcache, &fpregs);
8f2d3ea0
MK
135 }
136}
137
138/* Store register REGNUM back into the inferior. If REGNUM is -1, do
139 this for all registers (including the floating-point registers). */
140
abbc6945 141static void
28439f5e
PA
142m68kbsd_store_inferior_registers (struct target_ops *ops,
143 struct regcache *regcache, int regnum)
8f2d3ea0
MK
144{
145 if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
146 {
147 struct reg regs;
148
dfd4cc63 149 if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
9f8e0089 150 (PTRACE_TYPE_ARG3) &regs, 0) == -1)
e2e0b3e5 151 perror_with_name (_("Couldn't get registers"));
8f2d3ea0 152
56be3814 153 m68kbsd_collect_gregset (regcache, &regs, regnum);
8f2d3ea0 154
dfd4cc63 155 if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
9f8e0089 156 (PTRACE_TYPE_ARG3) &regs, 0) == -1)
e2e0b3e5 157 perror_with_name (_("Couldn't write registers"));
8f2d3ea0
MK
158 }
159
160 if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum))
161 {
162 struct fpreg fpregs;
163
dfd4cc63 164 if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
9f8e0089 165 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
e2e0b3e5 166 perror_with_name (_("Couldn't get floating point status"));
8f2d3ea0 167
56be3814 168 m68kbsd_collect_fpregset (regcache, &fpregs, regnum);
8f2d3ea0 169
dfd4cc63 170 if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
9f8e0089 171 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
e2e0b3e5 172 perror_with_name (_("Couldn't write floating point status"));
8f2d3ea0
MK
173 }
174}
cb162ff6
MK
175\f
176
177/* Support for debugging kernel virtual memory images. */
178
179#include <sys/types.h>
180#include <machine/pcb.h>
181
182#include "bsd-kvm.h"
183
184/* OpenBSD doesn't have these. */
185#ifndef PCB_REGS_FP
186#define PCB_REGS_FP 10
187#endif
188#ifndef PCB_REGS_SP
189#define PCB_REGS_SP 11
190#endif
191
192static int
193m68kbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
194{
195 int regnum, tmp;
196 int i = 0;
197
198 /* The following is true for NetBSD 1.6.2:
199
200 The pcb contains %d2...%d7, %a2...%a7 and %ps. This accounts for
201 all callee-saved registers. From this information we reconstruct
202 the register state as it would look when we just returned from
203 cpu_switch(). */
204
205 /* The stack pointer shouldn't be zero. */
206 if (pcb->pcb_regs[PCB_REGS_SP] == 0)
207 return 0;
208
209 for (regnum = M68K_D2_REGNUM; regnum <= M68K_D7_REGNUM; regnum++)
210 regcache_raw_supply (regcache, regnum, &pcb->pcb_regs[i++]);
211 for (regnum = M68K_A2_REGNUM; regnum <= M68K_SP_REGNUM; regnum++)
212 regcache_raw_supply (regcache, regnum, &pcb->pcb_regs[i++]);
213
214 tmp = pcb->pcb_ps & 0xffff;
215 regcache_raw_supply (regcache, M68K_PS_REGNUM, &tmp);
216
217 read_memory (pcb->pcb_regs[PCB_REGS_FP] + 4, (char *) &tmp, sizeof tmp);
218 regcache_raw_supply (regcache, M68K_PC_REGNUM, &tmp);
219
220 return 1;
221}
222\f
223
224/* Provide a prototype to silence -Wmissing-prototypes. */
225void _initialize_m68kbsd_nat (void);
226
227void
228_initialize_m68kbsd_nat (void)
229{
abbc6945
MK
230 struct target_ops *t;
231
232 t = inf_ptrace_target ();
bcfca652
MK
233 t->to_fetch_registers = m68kbsd_fetch_inferior_registers;
234 t->to_store_registers = m68kbsd_store_inferior_registers;
abbc6945
MK
235 add_target (t);
236
cb162ff6
MK
237 /* Support debugging kernel virtual memory images. */
238 bsd_kvm_add_target (m68kbsd_supply_pcb);
239}