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