* armnbsd-nat.c : ANSIfy all function declarations.
[platform/upstream/binutils.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 */