2011-05-23 Pedro Alves <pedro@codesourcery.com>
[deliverable/binutils-gdb.git] / gdb / m68kbsd-nat.c
CommitLineData
8f2d3ea0
MK
1/* Native-dependent code for Motorola 68000 BSD's.
2
7b6bb8da
JB
3 Copyright (C) 2004, 2007, 2008, 2009, 2010, 2011
4 Free Software Foundation, Inc.
8f2d3ea0
MK
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
8f2d3ea0
MK
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
8f2d3ea0
MK
20
21#include "defs.h"
cb162ff6 22#include "gdbcore.h"
8f2d3ea0
MK
23#include "inferior.h"
24#include "regcache.h"
25
26#include "gdb_assert.h"
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"
8f2d3ea0
MK
33
34static int
35m68kbsd_gregset_supplies_p (int regnum)
36{
37 return (regnum >= M68K_D0_REGNUM && regnum <= M68K_PC_REGNUM);
38}
39
40static int
41m68kbsd_fpregset_supplies_p (int regnum)
42{
43 return (regnum >= M68K_FP0_REGNUM && regnum <= M68K_FPI_REGNUM);
44}
45
46/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
47
48static void
49m68kbsd_supply_gregset (struct regcache *regcache, const void *gregs)
50{
51 const char *regs = gregs;
52 int regnum;
53
54 for (regnum = M68K_D0_REGNUM; regnum <= M68K_PC_REGNUM; regnum++)
55 regcache_raw_supply (regcache, regnum, regs + regnum * 4);
56}
57
58/* Supply the floating-point registers stored in FPREGS to REGCACHE. */
59
60static void
61m68kbsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
62{
6ba38425 63 struct gdbarch *gdbarch = get_regcache_arch (regcache);
8f2d3ea0
MK
64 const char *regs = fpregs;
65 int regnum;
66
67 for (regnum = M68K_FP0_REGNUM; regnum <= M68K_FPI_REGNUM; regnum++)
68 regcache_raw_supply (regcache, regnum,
6ba38425 69 regs + m68kbsd_fpreg_offset (gdbarch, regnum));
8f2d3ea0
MK
70}
71
72/* Collect the general-purpose registers from REGCACHE and store them
73 in GREGS. */
74
75static void
76m68kbsd_collect_gregset (const struct regcache *regcache,
77 void *gregs, int regnum)
78{
79 char *regs = gregs;
80 int i;
81
82 for (i = M68K_D0_REGNUM; i <= M68K_PC_REGNUM; i++)
83 {
84 if (regnum == -1 || regnum == i)
5df97fde 85 regcache_raw_collect (regcache, i, regs + i * 4);
8f2d3ea0
MK
86 }
87}
88
89/* Collect the floating-point registers from REGCACHE and store them
90 in FPREGS. */
91
92static void
93m68kbsd_collect_fpregset (struct regcache *regcache,
94 void *fpregs, int regnum)
95{
6ba38425 96 struct gdbarch *gdbarch = get_regcache_arch (regcache);
8f2d3ea0
MK
97 char *regs = fpregs;
98 int i;
99
100 for (i = M68K_FP0_REGNUM; i <= M68K_FPI_REGNUM; i++)
101 {
102 if (regnum == -1 || regnum == i)
6ba38425
UW
103 regcache_raw_collect (regcache, i,
104 regs + m68kbsd_fpreg_offset (gdbarch, i));
8f2d3ea0
MK
105 }
106}
107\f
108
109/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
110 for all registers (including the floating-point registers). */
111
abbc6945 112static void
28439f5e
PA
113m68kbsd_fetch_inferior_registers (struct target_ops *ops,
114 struct regcache *regcache, int regnum)
8f2d3ea0
MK
115{
116 if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
117 {
118 struct reg regs;
119
120 if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
9f8e0089 121 (PTRACE_TYPE_ARG3) &regs, 0) == -1)
e2e0b3e5 122 perror_with_name (_("Couldn't get registers"));
8f2d3ea0 123
56be3814 124 m68kbsd_supply_gregset (regcache, &regs);
8f2d3ea0
MK
125 }
126
127 if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum))
128 {
129 struct fpreg fpregs;
130
131 if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
9f8e0089 132 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
e2e0b3e5 133 perror_with_name (_("Couldn't get floating point status"));
8f2d3ea0 134
56be3814 135 m68kbsd_supply_fpregset (regcache, &fpregs);
8f2d3ea0
MK
136 }
137}
138
139/* Store register REGNUM back into the inferior. If REGNUM is -1, do
140 this for all registers (including the floating-point registers). */
141
abbc6945 142static void
28439f5e
PA
143m68kbsd_store_inferior_registers (struct target_ops *ops,
144 struct regcache *regcache, int regnum)
8f2d3ea0
MK
145{
146 if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
147 {
148 struct reg regs;
149
150 if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
9f8e0089 151 (PTRACE_TYPE_ARG3) &regs, 0) == -1)
e2e0b3e5 152 perror_with_name (_("Couldn't get registers"));
8f2d3ea0 153
56be3814 154 m68kbsd_collect_gregset (regcache, &regs, regnum);
8f2d3ea0
MK
155
156 if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
9f8e0089 157 (PTRACE_TYPE_ARG3) &regs, 0) == -1)
e2e0b3e5 158 perror_with_name (_("Couldn't write registers"));
8f2d3ea0
MK
159 }
160
161 if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum))
162 {
163 struct fpreg fpregs;
164
165 if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
9f8e0089 166 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
e2e0b3e5 167 perror_with_name (_("Couldn't get floating point status"));
8f2d3ea0 168
56be3814 169 m68kbsd_collect_fpregset (regcache, &fpregs, regnum);
8f2d3ea0
MK
170
171 if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
9f8e0089 172 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
e2e0b3e5 173 perror_with_name (_("Couldn't write floating point status"));
8f2d3ea0
MK
174 }
175}
cb162ff6
MK
176\f
177
178/* Support for debugging kernel virtual memory images. */
179
180#include <sys/types.h>
181#include <machine/pcb.h>
182
183#include "bsd-kvm.h"
184
185/* OpenBSD doesn't have these. */
186#ifndef PCB_REGS_FP
187#define PCB_REGS_FP 10
188#endif
189#ifndef PCB_REGS_SP
190#define PCB_REGS_SP 11
191#endif
192
193static int
194m68kbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
195{
196 int regnum, tmp;
197 int i = 0;
198
199 /* The following is true for NetBSD 1.6.2:
200
201 The pcb contains %d2...%d7, %a2...%a7 and %ps. This accounts for
202 all callee-saved registers. From this information we reconstruct
203 the register state as it would look when we just returned from
204 cpu_switch(). */
205
206 /* The stack pointer shouldn't be zero. */
207 if (pcb->pcb_regs[PCB_REGS_SP] == 0)
208 return 0;
209
210 for (regnum = M68K_D2_REGNUM; regnum <= M68K_D7_REGNUM; regnum++)
211 regcache_raw_supply (regcache, regnum, &pcb->pcb_regs[i++]);
212 for (regnum = M68K_A2_REGNUM; regnum <= M68K_SP_REGNUM; regnum++)
213 regcache_raw_supply (regcache, regnum, &pcb->pcb_regs[i++]);
214
215 tmp = pcb->pcb_ps & 0xffff;
216 regcache_raw_supply (regcache, M68K_PS_REGNUM, &tmp);
217
218 read_memory (pcb->pcb_regs[PCB_REGS_FP] + 4, (char *) &tmp, sizeof tmp);
219 regcache_raw_supply (regcache, M68K_PC_REGNUM, &tmp);
220
221 return 1;
222}
223\f
224
225/* Provide a prototype to silence -Wmissing-prototypes. */
226void _initialize_m68kbsd_nat (void);
227
228void
229_initialize_m68kbsd_nat (void)
230{
abbc6945
MK
231 struct target_ops *t;
232
233 t = inf_ptrace_target ();
bcfca652
MK
234 t->to_fetch_registers = m68kbsd_fetch_inferior_registers;
235 t->to_store_registers = m68kbsd_store_inferior_registers;
abbc6945
MK
236 add_target (t);
237
cb162ff6
MK
238 /* Support debugging kernel virtual memory images. */
239 bsd_kvm_add_target (m68kbsd_supply_pcb);
240}
This page took 0.550974 seconds and 4 git commands to generate.