gdb/gdbserver:
[deliverable/binutils-gdb.git] / gdb / hppanbsd-nat.c
CommitLineData
af5ca30d
NH
1/* Native-dependent code for NetBSD/hppa.
2
0b302171 3 Copyright (C) 2008-2012 Free Software Foundation, Inc.
af5ca30d
NH
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
5b1ba0e5 9 the Free Software Foundation; either version 3 of the License, or
af5ca30d
NH
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
5b1ba0e5 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
af5ca30d
NH
19
20#include "defs.h"
21#include "inferior.h"
22#include "regcache.h"
23
24#include <sys/types.h>
25#include <sys/ptrace.h>
26#include <machine/reg.h>
27
28#include "hppa-tdep.h"
29#include "inf-ptrace.h"
30
31#include "nbsd-nat.h"
32
33static int
34hppanbsd_gregset_supplies_p (int regnum)
35{
36 return ((regnum >= HPPA_R0_REGNUM && regnum <= HPPA_R31_REGNUM) ||
37 (regnum >= HPPA_SAR_REGNUM && regnum <= HPPA_PCSQ_TAIL_REGNUM) ||
38 regnum == HPPA_IPSW_REGNUM ||
39 (regnum >= HPPA_SR4_REGNUM && regnum <= HPPA_SR4_REGNUM + 5));
40}
41
42static int
43hppanbsd_fpregset_supplies_p (int regnum)
44{
45 return (regnum >= HPPA_FP0_REGNUM && regnum <= HPPA_FP31R_REGNUM);
46}
47
48/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
49
50static void
51hppanbsd_supply_gregset (struct regcache *regcache, const void *gregs)
52{
53 const char *regs = gregs;
54 const int *r = gregs;
55 int regnum;
56
57 for (regnum = HPPA_R1_REGNUM; regnum <= HPPA_R31_REGNUM; regnum++)
58 regcache_raw_supply (regcache, regnum, regs + regnum * 4);
59
60 regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs + 32 * 4);
61 regcache_raw_supply (regcache, HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
62 regcache_raw_supply (regcache, HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
63 regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
64 regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
65 regcache_raw_supply (regcache, HPPA_IPSW_REGNUM, regs);
66 regcache_raw_supply (regcache, HPPA_SR4_REGNUM, regs + 41 * 4);
67 regcache_raw_supply (regcache, HPPA_SR4_REGNUM + 1, regs + 37 * 4);
68 regcache_raw_supply (regcache, HPPA_SR4_REGNUM + 2, regs + 38 * 4);
69 regcache_raw_supply (regcache, HPPA_SR4_REGNUM + 3, regs + 39 * 4);
70 regcache_raw_supply (regcache, HPPA_SR4_REGNUM + 4, regs + 40 * 4);
71}
72
73/* Supply the floating-point registers stored in FPREGS to REGCACHE. */
74
75static void
76hppanbsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
77{
78 const char *regs = fpregs;
79 int regnum;
80
81 for (regnum = HPPA_FP0_REGNUM; regnum <= HPPA_FP31R_REGNUM;
82 regnum += 2, regs += 8)
83 {
84 regcache_raw_supply (regcache, regnum, regs);
85 regcache_raw_supply (regcache, regnum + 1, regs + 4);
86 }
87}
88
89/* Collect the general-purpose registers from REGCACHE and store them
90 in GREGS. */
91
92static void
93hppanbsd_collect_gregset (const struct regcache *regcache,
94 void *gregs, int regnum)
95{
96 char *regs = gregs;
97 int *r = gregs;
98 int i;
99
100 for (i = HPPA_R1_REGNUM; i <= HPPA_R31_REGNUM; i++)
101 {
102 if (regnum == -1 || regnum == i)
103 regcache_raw_collect (regcache, i, regs + i * 4);
104 }
105
106 if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
107 regcache_raw_collect (regcache, HPPA_IPSW_REGNUM, regs);
108 if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
109 regcache_raw_collect (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
110 if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
111 regcache_raw_collect (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
112
113 if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
114 regcache_raw_collect (regcache, HPPA_SAR_REGNUM, regs + 32 * 4);
115 if (regnum == -1 || regnum == HPPA_PCSQ_HEAD_REGNUM)
116 regcache_raw_collect (regcache, HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
117 if (regnum == -1 || regnum == HPPA_PCSQ_TAIL_REGNUM)
118 regcache_raw_collect (regcache, HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
119 if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
120 regcache_raw_collect (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
121 if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
122 regcache_raw_collect (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
123 if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
124 regcache_raw_collect (regcache, HPPA_IPSW_REGNUM, regs);
125 if (regnum == -1 || regnum == HPPA_SR4_REGNUM)
126 regcache_raw_collect (regcache, HPPA_SR4_REGNUM, regs + 41 * 4);
127 if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 1)
128 regcache_raw_collect (regcache, HPPA_SR4_REGNUM + 1, regs + 37 * 4);
129 if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 2)
130 regcache_raw_collect (regcache, HPPA_SR4_REGNUM + 2, regs + 38 * 4);
131 if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 3)
132 regcache_raw_collect (regcache, HPPA_SR4_REGNUM + 3, regs + 39 * 4);
133 if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 4)
134 regcache_raw_collect (regcache, HPPA_SR4_REGNUM + 4, regs + 40 * 4);
135}
136
137/* Collect the floating-point registers from REGCACHE and store them
138 in FPREGS. */
139
140static void
141hppanbsd_collect_fpregset (struct regcache *regcache,
142 void *fpregs, int regnum)
143{
144 char *regs = fpregs;
145 int i;
146
147 for (i = HPPA_FP0_REGNUM; i <= HPPA_FP31R_REGNUM; i += 2, regs += 8)
148 {
149 if (regnum == -1 || regnum == i || regnum == i + 1)
150 {
151 regcache_raw_collect (regcache, i, regs);
152 regcache_raw_collect (regcache, i + 1, regs + 4);
153 }
154 }
155}
156\f
157
158/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
159 for all registers (including the floating-point registers). */
160
161static void
28439f5e
PA
162hppanbsd_fetch_registers (struct target_ops *ops,
163 struct regcache *regcache, int regnum)
af5ca30d
NH
164
165{
166 if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
167 {
168 struct reg regs;
169
170 if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
171 (PTRACE_TYPE_ARG3) &regs, 0) == -1)
172 perror_with_name (_("Couldn't get registers"));
173
174 hppanbsd_supply_gregset (regcache, &regs);
175 }
176
177 if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum))
178 {
179 struct fpreg fpregs;
180
181 if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
182 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
183 perror_with_name (_("Couldn't get floating point status"));
184
185 hppanbsd_supply_fpregset (regcache, &fpregs);
186 }
187}
188
189/* Store register REGNUM back into the inferior. If REGNUM is -1, do
190 this for all registers (including the floating-point registers). */
191
192static void
28439f5e
PA
193hppanbsd_store_registers (struct target_ops *ops,
194 struct regcache *regcache, int regnum)
af5ca30d
NH
195{
196 if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
197 {
198 struct reg regs;
199
200 if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
201 (PTRACE_TYPE_ARG3) &regs, 0) == -1)
202 perror_with_name (_("Couldn't get registers"));
203
204 hppanbsd_collect_gregset (regcache, &regs, regnum);
205
206 if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
207 (PTRACE_TYPE_ARG3) &regs, 0) == -1)
208 perror_with_name (_("Couldn't write registers"));
209 }
210
211 if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum))
212 {
213 struct fpreg fpregs;
214
215 if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
216 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
217 perror_with_name (_("Couldn't get floating point status"));
218
219 hppanbsd_collect_fpregset (regcache, &fpregs, regnum);
220
221 if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
222 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
223 perror_with_name (_("Couldn't write floating point status"));
224 }
225}
226
227
228/* Provide a prototype to silence -Wmissing-prototypes. */
229void _initialize_hppanbsd_nat (void);
230
231void
232_initialize_hppanbsd_nat (void)
233{
234 struct target_ops *t;
235
236 /* Add some extra features to the ptrace target. */
237 t = inf_ptrace_target ();
238
239 t->to_fetch_registers = hppanbsd_fetch_registers;
240 t->to_store_registers = hppanbsd_store_registers;
241
242 t->to_pid_to_exec_file = nbsd_pid_to_exec_file;
243
244 add_target (t);
245}
This page took 0.412968 seconds and 4 git commands to generate.