* armnbsd-nat.c : ANSIfy all function declarations.
[deliverable/binutils-gdb.git] / gdb / armnbsd-nat.c
1 /* Native-dependent code for BSD Unix running on ARM's, for GDB.
2 Copyright 1988, 1989, 1991, 1992, 1994, 1996, 1999, 2002
3 Free Software Foundation, Inc.
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
9 the Free Software Foundation; either version 2 of the License, or
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
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22 #include "defs.h"
23
24 #include "arm-tdep.h"
25
26 #ifdef FETCH_INFERIOR_REGISTERS
27 #include <sys/types.h>
28 #include <sys/ptrace.h>
29 #include <machine/reg.h>
30 #include <machine/frame.h>
31 #include "inferior.h"
32 #include "regcache.h"
33
34 extern int arm_apcs_32;
35
36 static void
37 fetch_register (int regno)
38 {
39 struct reg inferior_registers;
40 int ret;
41
42 ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
43 (PTRACE_ARG3_TYPE) &inferior_registers, 0);
44
45 if (ret < 0)
46 {
47 warning ("unable to fetch general register");
48 return;
49 }
50
51 switch (regno)
52 {
53 case ARM_SP_REGNUM:
54 supply_register (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
55 break;
56
57 case ARM_LR_REGNUM:
58 supply_register (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
59 break;
60
61 case ARM_PC_REGNUM:
62 /* This is ok: we're running native... */
63 inferior_registers.r_pc = ADDR_BITS_REMOVE (inferior_registers.r_pc);
64 supply_register (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
65 break;
66
67 case ARM_PS_REGNUM:
68 if (arm_apcs_32)
69 supply_register (ARM_PS_REGNUM, (char *) &inferior_registers.r_cpsr);
70 else
71 supply_register (ARM_PS_REGNUM, (char *) &inferior_registers.r_pc);
72 break;
73
74 default:
75 supply_register (regno, (char *) &inferior_registers.r[regno]);
76 break;
77 }
78 }
79
80 static void
81 fetch_regs ()
82 {
83 struct reg inferior_registers;
84 int ret;
85 int regno;
86
87 ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
88 (PTRACE_ARG3_TYPE) &inferior_registers, 0);
89
90 if (ret < 0)
91 {
92 warning ("unable to fetch general registers");
93 return;
94 }
95
96 for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
97 supply_register (regno, (char *) &inferior_registers.r[regno]);
98
99 supply_register (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
100 supply_register (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
101 /* This is ok: we're running native... */
102 inferior_registers.r_pc = ADDR_BITS_REMOVE (inferior_registers.r_pc);
103 supply_register (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
104
105 if (arm_apcs_32)
106 supply_register (ARM_PS_REGNUM, (char *) &inferior_registers.r_cpsr);
107 else
108 supply_register (ARM_PS_REGNUM, (char *) &inferior_registers.r_pc);
109 }
110
111 static void
112 fetch_fp_register (int regno)
113 {
114 struct fpreg inferior_fp_registers;
115 int ret;
116
117 ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
118 (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
119
120 if (ret < 0)
121 {
122 warning ("unable to fetch floating-point register");
123 return;
124 }
125
126 switch (regno)
127 {
128 case ARM_FPS_REGNUM:
129 supply_register (ARM_FPS_REGNUM,
130 (char *) &inferior_fp_registers.fpr_fpsr);
131 break;
132
133 default:
134 supply_register
135 (regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
136 break;
137 }
138 }
139
140 static void
141 fetch_fp_regs ()
142 {
143 struct fpreg inferior_fp_registers;
144 int ret;
145 int regno;
146
147 ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
148 (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
149
150 if (ret < 0)
151 {
152 warning ("unable to fetch general registers");
153 return;
154 }
155
156 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
157 supply_register
158 (regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
159
160 supply_register (ARM_FPS_REGNUM, (char *) &inferior_fp_registers.fpr_fpsr);
161 }
162
163 void
164 fetch_inferior_registers (int regno)
165 {
166 if (regno >= 0)
167 {
168 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
169 fetch_register (regno);
170 else
171 fetch_fp_register (regno);
172 }
173 else
174 {
175 fetch_regs ();
176 fetch_fp_regs ();
177 }
178 }
179
180
181 static void
182 store_register (int regno)
183 {
184 struct reg inferior_registers;
185 int ret;
186
187 ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
188 (PTRACE_ARG3_TYPE) &inferior_registers, 0);
189
190 if (ret < 0)
191 {
192 warning ("unable to fetch general registers");
193 return;
194 }
195
196 switch (regno)
197 {
198 case ARM_SP_REGNUM:
199 regcache_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
200 break;
201
202 case ARM_LR_REGNUM:
203 regcache_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
204 break;
205
206 case ARM_PC_REGNUM:
207 if (arm_apcs_32)
208 regcache_collect (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
209 else
210 {
211 unsigned pc_val;
212
213 regcache_collect (ARM_PC_REGNUM, (char *) &pc_val);
214
215 pc_val = ADDR_BITS_REMOVE (pc_val);
216 inferior_registers.r_pc
217 ^= ADDR_BITS_REMOVE (inferior_registers.r_pc);
218 inferior_registers.r_pc |= pc_val;
219 }
220 break;
221
222 case ARM_PS_REGNUM:
223 if (arm_apcs_32)
224 regcache_collect (ARM_PS_REGNUM, (char *) &inferior_registers.r_cpsr);
225 else
226 {
227 unsigned psr_val;
228
229 regcache_collect (ARM_PS_REGNUM, (char *) &psr_val);
230
231 psr_val ^= ADDR_BITS_REMOVE (psr_val);
232 inferior_registers.r_pc = ADDR_BITS_REMOVE (inferior_registers.r_pc);
233 inferior_registers.r_pc |= psr_val;
234 }
235 break;
236
237 default:
238 regcache_collect (regno, (char *) &inferior_registers.r[regno]);
239 break;
240 }
241
242 ret = ptrace (PT_SETREGS, PIDGET (inferior_ptid),
243 (PTRACE_ARG3_TYPE) &inferior_registers, 0);
244
245 if (ret < 0)
246 warning ("unable to write register %d to inferior", regno);
247 }
248
249 static void
250 store_regs ()
251 {
252 struct reg inferior_registers;
253 int ret;
254 int regno;
255
256
257 for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
258 regcache_collect (regno, (char *) &inferior_registers.r[regno]);
259
260 regcache_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
261 regcache_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
262
263 if (arm_apcs_32)
264 {
265 regcache_collect (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
266 regcache_collect (ARM_PS_REGNUM, (char *) &inferior_registers.r_cpsr);
267 }
268 else
269 {
270 unsigned pc_val;
271 unsigned psr_val;
272
273 regcache_collect (ARM_PC_REGNUM, (char *) &pc_val);
274 regcache_collect (ARM_PS_REGNUM, (char *) &psr_val);
275
276 pc_val = ADDR_BITS_REMOVE (pc_val);
277 psr_val ^= ADDR_BITS_REMOVE (psr_val);
278
279 inferior_registers.r_pc = pc_val | psr_val;
280 }
281
282 ret = ptrace (PT_SETREGS, PIDGET (inferior_ptid),
283 (PTRACE_ARG3_TYPE) &inferior_registers, 0);
284
285 if (ret < 0)
286 warning ("unable to store general registers");
287 }
288
289 static void
290 store_fp_register (int regno)
291 {
292 struct fpreg inferior_fp_registers;
293 int ret;
294
295 ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
296 (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
297
298 if (ret < 0)
299 {
300 warning ("unable to fetch floating-point registers");
301 return;
302 }
303
304 switch (regno)
305 {
306 case ARM_FPS_REGNUM:
307 regcache_collect (ARM_FPS_REGNUM,
308 (char *) &inferior_fp_registers.fpr_fpsr);
309 break;
310
311 default:
312 regcache_collect
313 (regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
314 break;
315 }
316
317 ret = ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
318 (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
319
320 if (ret < 0)
321 warning ("unable to write register %d to inferior", regno);
322 }
323
324 static void
325 store_fp_regs ()
326 {
327 struct fpreg inferior_fp_registers;
328 int ret;
329 int regno;
330
331
332 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
333 regcache_collect
334 (regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
335
336 regcache_collect (ARM_FPS_REGNUM, (char *) &inferior_fp_registers.fpr_fpsr);
337
338 ret = ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
339 (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
340
341 if (ret < 0)
342 warning ("unable to store floating-point registers");
343 }
344
345 void
346 store_inferior_registers (int regno)
347 {
348 if (regno >= 0)
349 {
350 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
351 store_register (regno);
352 else
353 store_fp_register (regno);
354 }
355 else
356 {
357 store_regs ();
358 store_fp_regs ();
359 }
360 }
361
362 struct md_core
363 {
364 struct reg intreg;
365 struct fpreg freg;
366 };
367
368 void
369 fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
370 int which, CORE_ADDR ignore)
371 {
372 struct md_core *core_reg = (struct md_core *) core_reg_sect;
373
374 /* integer registers */
375 memcpy (&registers[REGISTER_BYTE (0)], &core_reg->intreg,
376 sizeof (struct reg));
377 /* floating point registers */
378 /* XXX */
379 }
380
381 #else
382 #error Not FETCH_INFERIOR_REGISTERS
383 #endif /* !FETCH_INFERIOR_REGISTERS */
This page took 0.037 seconds and 4 git commands to generate.