* hppa-tdep.c (_initialize_hppa_tdep): Add declaration.
[binutils-gdb.git] / gdb / armnbsd-nat.c
blob266c83b22e767cb1c1defa935073d81b571ef84b
1 /* Native-dependent code for BSD Unix running on ARM's, for GDB.
3 Copyright (C) 1988, 1989, 1991, 1992, 1994, 1996, 1999, 2002, 2004, 2007,
4 2008, 2009 Free Software Foundation, Inc.
6 This file is part of GDB.
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
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
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.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 #include "defs.h"
22 #include "gdbcore.h"
23 #include "inferior.h"
24 #include "regcache.h"
25 #include "target.h"
27 #include "gdb_string.h"
28 #include <sys/types.h>
29 #include <sys/ptrace.h>
30 #include <machine/reg.h>
31 #include <machine/frame.h>
33 #include "arm-tdep.h"
34 #include "inf-ptrace.h"
36 extern int arm_apcs_32;
38 static void
39 arm_supply_gregset (struct regcache *regcache, struct reg *gregset)
41 int regno;
42 CORE_ADDR r_pc;
44 /* Integer registers. */
45 for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
46 regcache_raw_supply (regcache, regno, (char *) &gregset->r[regno]);
48 regcache_raw_supply (regcache, ARM_SP_REGNUM,
49 (char *) &gregset->r_sp);
50 regcache_raw_supply (regcache, ARM_LR_REGNUM,
51 (char *) &gregset->r_lr);
52 /* This is ok: we're running native... */
53 r_pc = gdbarch_addr_bits_remove (get_regcache_arch (regcache), gregset->r_pc);
54 regcache_raw_supply (regcache, ARM_PC_REGNUM, (char *) &r_pc);
56 if (arm_apcs_32)
57 regcache_raw_supply (regcache, ARM_PS_REGNUM,
58 (char *) &gregset->r_cpsr);
59 else
60 regcache_raw_supply (regcache, ARM_PS_REGNUM,
61 (char *) &gregset->r_pc);
64 static void
65 arm_supply_fparegset (struct regcache *regcache, struct fpreg *fparegset)
67 int regno;
69 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
70 regcache_raw_supply (regcache, regno,
71 (char *) &fparegset->fpr[regno - ARM_F0_REGNUM]);
73 regcache_raw_supply (regcache, ARM_FPS_REGNUM,
74 (char *) &fparegset->fpr_fpsr);
77 static void
78 fetch_register (struct regcache *regcache, int regno)
80 struct reg inferior_registers;
81 int ret;
83 ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
84 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
86 if (ret < 0)
88 warning (_("unable to fetch general register"));
89 return;
92 switch (regno)
94 case ARM_SP_REGNUM:
95 regcache_raw_supply (regcache, ARM_SP_REGNUM,
96 (char *) &inferior_registers.r_sp);
97 break;
99 case ARM_LR_REGNUM:
100 regcache_raw_supply (regcache, ARM_LR_REGNUM,
101 (char *) &inferior_registers.r_lr);
102 break;
104 case ARM_PC_REGNUM:
105 /* This is ok: we're running native... */
106 inferior_registers.r_pc = gdbarch_addr_bits_remove
107 (get_regcache_arch (regcache),
108 inferior_registers.r_pc);
109 regcache_raw_supply (regcache, ARM_PC_REGNUM,
110 (char *) &inferior_registers.r_pc);
111 break;
113 case ARM_PS_REGNUM:
114 if (arm_apcs_32)
115 regcache_raw_supply (regcache, ARM_PS_REGNUM,
116 (char *) &inferior_registers.r_cpsr);
117 else
118 regcache_raw_supply (regcache, ARM_PS_REGNUM,
119 (char *) &inferior_registers.r_pc);
120 break;
122 default:
123 regcache_raw_supply (regcache, regno,
124 (char *) &inferior_registers.r[regno]);
125 break;
129 static void
130 fetch_regs (struct regcache *regcache)
132 struct reg inferior_registers;
133 int ret;
134 int regno;
136 ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
137 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
139 if (ret < 0)
141 warning (_("unable to fetch general registers"));
142 return;
145 arm_supply_gregset (regcache, &inferior_registers);
148 static void
149 fetch_fp_register (struct regcache *regcache, int regno)
151 struct fpreg inferior_fp_registers;
152 int ret;
154 ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
155 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
157 if (ret < 0)
159 warning (_("unable to fetch floating-point register"));
160 return;
163 switch (regno)
165 case ARM_FPS_REGNUM:
166 regcache_raw_supply (regcache, ARM_FPS_REGNUM,
167 (char *) &inferior_fp_registers.fpr_fpsr);
168 break;
170 default:
171 regcache_raw_supply (regcache, regno,
172 (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
173 break;
177 static void
178 fetch_fp_regs (struct regcache *regcache)
180 struct fpreg inferior_fp_registers;
181 int ret;
182 int regno;
184 ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
185 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
187 if (ret < 0)
189 warning (_("unable to fetch general registers"));
190 return;
193 arm_supply_fparegset (regcache, &inferior_fp_registers);
196 static void
197 armnbsd_fetch_registers (struct target_ops *ops,
198 struct regcache *regcache, int regno)
200 if (regno >= 0)
202 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
203 fetch_register (regcache, regno);
204 else
205 fetch_fp_register (regcache, regno);
207 else
209 fetch_regs (regcache);
210 fetch_fp_regs (regcache);
215 static void
216 store_register (const struct regcache *regcache, int regno)
218 struct gdbarch *gdbarch = get_regcache_arch (regcache);
219 struct reg inferior_registers;
220 int ret;
222 ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
223 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
225 if (ret < 0)
227 warning (_("unable to fetch general registers"));
228 return;
231 switch (regno)
233 case ARM_SP_REGNUM:
234 regcache_raw_collect (regcache, ARM_SP_REGNUM,
235 (char *) &inferior_registers.r_sp);
236 break;
238 case ARM_LR_REGNUM:
239 regcache_raw_collect (regcache, ARM_LR_REGNUM,
240 (char *) &inferior_registers.r_lr);
241 break;
243 case ARM_PC_REGNUM:
244 if (arm_apcs_32)
245 regcache_raw_collect (regcache, ARM_PC_REGNUM,
246 (char *) &inferior_registers.r_pc);
247 else
249 unsigned pc_val;
251 regcache_raw_collect (regcache, ARM_PC_REGNUM,
252 (char *) &pc_val);
254 pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
255 inferior_registers.r_pc ^= gdbarch_addr_bits_remove
256 (gdbarch, inferior_registers.r_pc);
257 inferior_registers.r_pc |= pc_val;
259 break;
261 case ARM_PS_REGNUM:
262 if (arm_apcs_32)
263 regcache_raw_collect (regcache, ARM_PS_REGNUM,
264 (char *) &inferior_registers.r_cpsr);
265 else
267 unsigned psr_val;
269 regcache_raw_collect (regcache, ARM_PS_REGNUM,
270 (char *) &psr_val);
272 psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
273 inferior_registers.r_pc = gdbarch_addr_bits_remove
274 (gdbarch, inferior_registers.r_pc);
275 inferior_registers.r_pc |= psr_val;
277 break;
279 default:
280 regcache_raw_collect (regcache, regno,
281 (char *) &inferior_registers.r[regno]);
282 break;
285 ret = ptrace (PT_SETREGS, PIDGET (inferior_ptid),
286 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
288 if (ret < 0)
289 warning (_("unable to write register %d to inferior"), regno);
292 static void
293 store_regs (const struct regcache *regcache)
295 struct gdbarch *gdbarch = get_regcache_arch (regcache);
296 struct reg inferior_registers;
297 int ret;
298 int regno;
301 for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
302 regcache_raw_collect (regcache, regno,
303 (char *) &inferior_registers.r[regno]);
305 regcache_raw_collect (regcache, ARM_SP_REGNUM,
306 (char *) &inferior_registers.r_sp);
307 regcache_raw_collect (regcache, ARM_LR_REGNUM,
308 (char *) &inferior_registers.r_lr);
310 if (arm_apcs_32)
312 regcache_raw_collect (regcache, ARM_PC_REGNUM,
313 (char *) &inferior_registers.r_pc);
314 regcache_raw_collect (regcache, ARM_PS_REGNUM,
315 (char *) &inferior_registers.r_cpsr);
317 else
319 unsigned pc_val;
320 unsigned psr_val;
322 regcache_raw_collect (regcache, ARM_PC_REGNUM,
323 (char *) &pc_val);
324 regcache_raw_collect (regcache, ARM_PS_REGNUM,
325 (char *) &psr_val);
327 pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
328 psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
330 inferior_registers.r_pc = pc_val | psr_val;
333 ret = ptrace (PT_SETREGS, PIDGET (inferior_ptid),
334 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
336 if (ret < 0)
337 warning (_("unable to store general registers"));
340 static void
341 store_fp_register (const struct regcache *regcache, int regno)
343 struct fpreg inferior_fp_registers;
344 int ret;
346 ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
347 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
349 if (ret < 0)
351 warning (_("unable to fetch floating-point registers"));
352 return;
355 switch (regno)
357 case ARM_FPS_REGNUM:
358 regcache_raw_collect (regcache, ARM_FPS_REGNUM,
359 (char *) &inferior_fp_registers.fpr_fpsr);
360 break;
362 default:
363 regcache_raw_collect (regcache, regno,
364 (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
365 break;
368 ret = ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
369 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
371 if (ret < 0)
372 warning (_("unable to write register %d to inferior"), regno);
375 static void
376 store_fp_regs (const struct regcache *regcache)
378 struct fpreg inferior_fp_registers;
379 int ret;
380 int regno;
383 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
384 regcache_raw_collect (regcache, regno,
385 (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
387 regcache_raw_collect (regcache, ARM_FPS_REGNUM,
388 (char *) &inferior_fp_registers.fpr_fpsr);
390 ret = ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
391 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
393 if (ret < 0)
394 warning (_("unable to store floating-point registers"));
397 static void
398 armnbsd_store_registers (struct target_ops *ops,
399 struct regcache *regcache, int regno)
401 if (regno >= 0)
403 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
404 store_register (regcache, regno);
405 else
406 store_fp_register (regcache, regno);
408 else
410 store_regs (regcache);
411 store_fp_regs (regcache);
415 struct md_core
417 struct reg intreg;
418 struct fpreg freg;
421 static void
422 fetch_core_registers (struct regcache *regcache,
423 char *core_reg_sect, unsigned core_reg_size,
424 int which, CORE_ADDR ignore)
426 struct md_core *core_reg = (struct md_core *) core_reg_sect;
427 int regno;
428 CORE_ADDR r_pc;
430 arm_supply_gregset (regcache, &core_reg->intreg);
431 arm_supply_fparegset (regcache, &core_reg->freg);
434 static void
435 fetch_elfcore_registers (struct regcache *regcache,
436 char *core_reg_sect, unsigned core_reg_size,
437 int which, CORE_ADDR ignore)
439 struct reg gregset;
440 struct fpreg fparegset;
442 switch (which)
444 case 0: /* Integer registers. */
445 if (core_reg_size != sizeof (struct reg))
446 warning (_("wrong size of register set in core file"));
447 else
449 /* The memcpy may be unnecessary, but we can't really be sure
450 of the alignment of the data in the core file. */
451 memcpy (&gregset, core_reg_sect, sizeof (gregset));
452 arm_supply_gregset (regcache, &gregset);
454 break;
456 case 2:
457 if (core_reg_size != sizeof (struct fpreg))
458 warning (_("wrong size of FPA register set in core file"));
459 else
461 /* The memcpy may be unnecessary, but we can't really be sure
462 of the alignment of the data in the core file. */
463 memcpy (&fparegset, core_reg_sect, sizeof (fparegset));
464 arm_supply_fparegset (regcache, &fparegset);
466 break;
468 default:
469 /* Don't know what kind of register request this is; just ignore it. */
470 break;
474 static struct core_fns arm_netbsd_core_fns =
476 bfd_target_unknown_flavour, /* core_flovour. */
477 default_check_format, /* check_format. */
478 default_core_sniffer, /* core_sniffer. */
479 fetch_core_registers, /* core_read_registers. */
480 NULL
483 static struct core_fns arm_netbsd_elfcore_fns =
485 bfd_target_elf_flavour, /* core_flovour. */
486 default_check_format, /* check_format. */
487 default_core_sniffer, /* core_sniffer. */
488 fetch_elfcore_registers, /* core_read_registers. */
489 NULL
492 void
493 _initialize_arm_netbsd_nat (void)
495 struct target_ops *t;
497 t = inf_ptrace_target ();
498 t->to_fetch_registers = armnbsd_fetch_registers;
499 t->to_store_registers = armnbsd_store_registers;
500 add_target (t);
502 deprecated_add_core_fns (&arm_netbsd_core_fns);
503 deprecated_add_core_fns (&arm_netbsd_elfcore_fns);