]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/m68kbsd-nat.c
Updated copyright notices for most files.
[thirdparty/binutils-gdb.git] / gdb / m68kbsd-nat.c
CommitLineData
8f2d3ea0
MK
1/* Native-dependent code for Motorola 68000 BSD's.
2
0fb0cc75 3 Copyright (C) 2004, 2007, 2008, 2009 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
56be3814 112m68kbsd_fetch_inferior_registers (struct regcache *regcache, int regnum)
8f2d3ea0
MK
113{
114 if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
115 {
116 struct reg regs;
117
118 if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
9f8e0089 119 (PTRACE_TYPE_ARG3) &regs, 0) == -1)
e2e0b3e5 120 perror_with_name (_("Couldn't get registers"));
8f2d3ea0 121
56be3814 122 m68kbsd_supply_gregset (regcache, &regs);
8f2d3ea0
MK
123 }
124
125 if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum))
126 {
127 struct fpreg fpregs;
128
129 if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
9f8e0089 130 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
e2e0b3e5 131 perror_with_name (_("Couldn't get floating point status"));
8f2d3ea0 132
56be3814 133 m68kbsd_supply_fpregset (regcache, &fpregs);
8f2d3ea0
MK
134 }
135}
136
137/* Store register REGNUM back into the inferior. If REGNUM is -1, do
138 this for all registers (including the floating-point registers). */
139
abbc6945 140static void
56be3814 141m68kbsd_store_inferior_registers (struct regcache *regcache, int regnum)
8f2d3ea0
MK
142{
143 if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
144 {
145 struct reg regs;
146
147 if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
9f8e0089 148 (PTRACE_TYPE_ARG3) &regs, 0) == -1)
e2e0b3e5 149 perror_with_name (_("Couldn't get registers"));
8f2d3ea0 150
56be3814 151 m68kbsd_collect_gregset (regcache, &regs, regnum);
8f2d3ea0
MK
152
153 if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
9f8e0089 154 (PTRACE_TYPE_ARG3) &regs, 0) == -1)
e2e0b3e5 155 perror_with_name (_("Couldn't write registers"));
8f2d3ea0
MK
156 }
157
158 if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum))
159 {
160 struct fpreg fpregs;
161
162 if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
9f8e0089 163 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
e2e0b3e5 164 perror_with_name (_("Couldn't get floating point status"));
8f2d3ea0 165
56be3814 166 m68kbsd_collect_fpregset (regcache, &fpregs, regnum);
8f2d3ea0
MK
167
168 if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
9f8e0089 169 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
e2e0b3e5 170 perror_with_name (_("Couldn't write floating point status"));
8f2d3ea0
MK
171 }
172}
cb162ff6
MK
173\f
174
175/* Support for debugging kernel virtual memory images. */
176
177#include <sys/types.h>
178#include <machine/pcb.h>
179
180#include "bsd-kvm.h"
181
182/* OpenBSD doesn't have these. */
183#ifndef PCB_REGS_FP
184#define PCB_REGS_FP 10
185#endif
186#ifndef PCB_REGS_SP
187#define PCB_REGS_SP 11
188#endif
189
190static int
191m68kbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
192{
193 int regnum, tmp;
194 int i = 0;
195
196 /* The following is true for NetBSD 1.6.2:
197
198 The pcb contains %d2...%d7, %a2...%a7 and %ps. This accounts for
199 all callee-saved registers. From this information we reconstruct
200 the register state as it would look when we just returned from
201 cpu_switch(). */
202
203 /* The stack pointer shouldn't be zero. */
204 if (pcb->pcb_regs[PCB_REGS_SP] == 0)
205 return 0;
206
207 for (regnum = M68K_D2_REGNUM; regnum <= M68K_D7_REGNUM; regnum++)
208 regcache_raw_supply (regcache, regnum, &pcb->pcb_regs[i++]);
209 for (regnum = M68K_A2_REGNUM; regnum <= M68K_SP_REGNUM; regnum++)
210 regcache_raw_supply (regcache, regnum, &pcb->pcb_regs[i++]);
211
212 tmp = pcb->pcb_ps & 0xffff;
213 regcache_raw_supply (regcache, M68K_PS_REGNUM, &tmp);
214
215 read_memory (pcb->pcb_regs[PCB_REGS_FP] + 4, (char *) &tmp, sizeof tmp);
216 regcache_raw_supply (regcache, M68K_PC_REGNUM, &tmp);
217
218 return 1;
219}
220\f
221
222/* Provide a prototype to silence -Wmissing-prototypes. */
223void _initialize_m68kbsd_nat (void);
224
225void
226_initialize_m68kbsd_nat (void)
227{
abbc6945
MK
228 struct target_ops *t;
229
230 t = inf_ptrace_target ();
bcfca652
MK
231 t->to_fetch_registers = m68kbsd_fetch_inferior_registers;
232 t->to_store_registers = m68kbsd_store_inferior_registers;
abbc6945
MK
233 add_target (t);
234
cb162ff6
MK
235 /* Support debugging kernel virtual memory images. */
236 bsd_kvm_add_target (m68kbsd_supply_pcb);
237}