]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/alphabsd-nat.c
2011-01-07 Michael Snyder <msnyder@vmware.com>
[thirdparty/binutils-gdb.git] / gdb / alphabsd-nat.c
CommitLineData
448628fe 1/* Native-dependent code for Alpha BSD's.
07681759 2
7b6bb8da
JB
3 Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
4 2011 Free Software Foundation, Inc.
448628fe
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
448628fe
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/>. */
448628fe
MK
20
21#include "defs.h"
22#include "inferior.h"
4e052eda 23#include "regcache.h"
448628fe 24
dc129d82 25#include "alpha-tdep.h"
12bcb0fe 26#include "alphabsd-tdep.h"
0d6e4ad7 27#include "inf-ptrace.h"
dc129d82 28
448628fe
MK
29#include <sys/types.h>
30#include <sys/ptrace.h>
31#include <machine/reg.h>
32
33#ifdef HAVE_SYS_PROCFS_H
34#include <sys/procfs.h>
35#endif
36
37#ifndef HAVE_GREGSET_T
38typedef struct reg gregset_t;
39#endif
40
12bcb0fe
JT
41#ifndef HAVE_FPREGSET_T
42typedef struct fpreg fpregset_t;
43#endif
448628fe
MK
44
45#include "gregset.h"
46
12bcb0fe
JT
47/* Provide *regset() wrappers around the generic Alpha BSD register
48 supply/fill routines. */
448628fe
MK
49
50void
7f7fe91e 51supply_gregset (struct regcache *regcache, const gregset_t *gregsetp)
448628fe 52{
7f7fe91e 53 alphabsd_supply_reg (regcache, (const char *) gregsetp, -1);
448628fe
MK
54}
55
448628fe 56void
7f7fe91e 57fill_gregset (const struct regcache *regcache, gregset_t *gregsetp, int regno)
448628fe 58{
7f7fe91e 59 alphabsd_fill_reg (regcache, (char *) gregsetp, regno);
448628fe
MK
60}
61
448628fe 62void
7f7fe91e 63supply_fpregset (struct regcache *regcache, const fpregset_t *fpregsetp)
448628fe 64{
7f7fe91e 65 alphabsd_supply_fpreg (regcache, (const char *) fpregsetp, -1);
448628fe
MK
66}
67
448628fe 68void
0963b4bd
MS
69fill_fpregset (const struct regcache *regcache,
70 fpregset_t *fpregsetp, int regno)
448628fe 71{
7f7fe91e 72 alphabsd_fill_fpreg (regcache, (char *) fpregsetp, regno);
448628fe 73}
12bcb0fe 74\f
e771a871
JT
75/* Determine if PT_GETREGS fetches this register. */
76
77static int
78getregs_supplies (int regno)
79{
dc129d82 80 return ((regno >= ALPHA_V0_REGNUM && regno <= ALPHA_ZERO_REGNUM)
07681759 81 || regno >= ALPHA_PC_REGNUM);
e771a871
JT
82}
83
448628fe
MK
84/* Fetch register REGNO from the inferior. If REGNO is -1, do this
85 for all registers (including the floating point registers). */
86
0d6e4ad7 87static void
28439f5e
PA
88alphabsd_fetch_inferior_registers (struct target_ops *ops,
89 struct regcache *regcache, int regno)
448628fe 90{
e771a871
JT
91 if (regno == -1 || getregs_supplies (regno))
92 {
12bcb0fe 93 struct reg gregs;
e771a871
JT
94
95 if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
9f8e0089 96 (PTRACE_TYPE_ARG3) &gregs, 0) == -1)
edefbb7c 97 perror_with_name (_("Couldn't get registers"));
448628fe 98
56be3814 99 alphabsd_supply_reg (regcache, (char *) &gregs, regno);
e771a871
JT
100 if (regno != -1)
101 return;
102 }
448628fe 103
0963b4bd
MS
104 if (regno == -1
105 || regno >= gdbarch_fp0_regnum (get_regcache_arch (regcache)))
448628fe 106 {
12bcb0fe 107 struct fpreg fpregs;
448628fe 108
39f77062 109 if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
9f8e0089 110 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
edefbb7c 111 perror_with_name (_("Couldn't get floating point status"));
448628fe 112
56be3814 113 alphabsd_supply_fpreg (regcache, (char *) &fpregs, regno);
448628fe 114 }
448628fe
MK
115}
116
117/* Store register REGNO back into the inferior. If REGNO is -1, do
118 this for all registers (including the floating point registers). */
119
0d6e4ad7 120static void
28439f5e
PA
121alphabsd_store_inferior_registers (struct target_ops *ops,
122 struct regcache *regcache, int regno)
448628fe 123{
e771a871
JT
124 if (regno == -1 || getregs_supplies (regno))
125 {
12bcb0fe 126 struct reg gregs;
e771a871 127 if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
9f8e0089 128 (PTRACE_TYPE_ARG3) &gregs, 0) == -1)
edefbb7c 129 perror_with_name (_("Couldn't get registers"));
e771a871 130
56be3814 131 alphabsd_fill_reg (regcache, (char *) &gregs, regno);
448628fe 132
e771a871 133 if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
9f8e0089 134 (PTRACE_TYPE_ARG3) &gregs, 0) == -1)
edefbb7c 135 perror_with_name (_("Couldn't write registers"));
448628fe 136
e771a871
JT
137 if (regno != -1)
138 return;
139 }
448628fe 140
0963b4bd
MS
141 if (regno == -1
142 || regno >= gdbarch_fp0_regnum (get_regcache_arch (regcache)))
448628fe 143 {
12bcb0fe 144 struct fpreg fpregs;
448628fe 145
39f77062 146 if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
9f8e0089 147 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
edefbb7c 148 perror_with_name (_("Couldn't get floating point status"));
448628fe 149
56be3814 150 alphabsd_fill_fpreg (regcache, (char *) &fpregs, regno);
448628fe 151
39f77062 152 if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
9f8e0089 153 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
edefbb7c 154 perror_with_name (_("Couldn't write floating point status"));
448628fe
MK
155 }
156}
4816ec69
MK
157\f
158
159/* Support for debugging kernel virtual memory images. */
160
161#include <sys/types.h>
162#include <sys/signal.h>
163#include <machine/pcb.h>
164
165#include "bsd-kvm.h"
166
167static int
168alphabsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
169{
170 int regnum;
171
172 /* The following is true for OpenBSD 3.9:
173
174 The pcb contains the register state at the context switch inside
175 cpu_switch(). */
176
177 /* The stack pointer shouldn't be zero. */
178 if (pcb->pcb_hw.apcb_ksp == 0)
179 return 0;
180
181 regcache_raw_supply (regcache, ALPHA_SP_REGNUM, &pcb->pcb_hw.apcb_ksp);
182
183 for (regnum = ALPHA_S0_REGNUM; regnum < ALPHA_A0_REGNUM; regnum++)
184 regcache_raw_supply (regcache, regnum,
185 &pcb->pcb_context[regnum - ALPHA_S0_REGNUM]);
186 regcache_raw_supply (regcache, ALPHA_RA_REGNUM, &pcb->pcb_context[7]);
187
188 return 1;
189}
190\f
0d6e4ad7
MK
191
192/* Provide a prototype to silence -Wmissing-prototypes. */
193void _initialize_alphabsd_nat (void);
194
195void
196_initialize_alphabsd_nat (void)
197{
198 struct target_ops *t;
199
200 t = inf_ptrace_target ();
201 t->to_fetch_registers = alphabsd_fetch_inferior_registers;
202 t->to_store_registers = alphabsd_store_inferior_registers;
203 add_target (t);
4816ec69
MK
204
205 /* Support debugging kernel virtual memory images. */
206 bsd_kvm_add_target (alphabsd_supply_pcb);
0d6e4ad7 207}