1 /* Native-dependent code for BSD Unix running on ARM's, for GDB.
3 Copyright 1988, 1989, 1991, 1992, 1994, 1996, 1999, 2002, 2004
4 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 2 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, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
25 #ifndef FETCH_INFERIOR_REGISTERS
26 #error Not FETCH_INFERIOR_REGISTERS
27 #endif /* !FETCH_INFERIOR_REGISTERS */
31 #include <sys/types.h>
32 #include <sys/ptrace.h>
33 #include <machine/reg.h>
34 #include <machine/frame.h>
39 extern int arm_apcs_32;
42 supply_gregset (struct reg *gregset)
47 /* Integer registers. */
48 for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
49 regcache_raw_supply (current_regcache, regno, (char *) &gregset->r[regno]);
51 regcache_raw_supply (current_regcache, ARM_SP_REGNUM,
52 (char *) &gregset->r_sp);
53 regcache_raw_supply (current_regcache, ARM_LR_REGNUM,
54 (char *) &gregset->r_lr);
55 /* This is ok: we're running native... */
56 r_pc = ADDR_BITS_REMOVE (gregset->r_pc);
57 regcache_raw_supply (current_regcache, ARM_PC_REGNUM, (char *) &r_pc);
60 regcache_raw_supply (current_regcache, ARM_PS_REGNUM,
61 (char *) &gregset->r_cpsr);
63 regcache_raw_supply (current_regcache, ARM_PS_REGNUM,
64 (char *) &gregset->r_pc);
68 supply_fparegset (struct fpreg *fparegset)
72 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
73 regcache_raw_supply (current_regcache, regno,
74 (char *) &fparegset->fpr[regno - ARM_F0_REGNUM]);
76 regcache_raw_supply (current_regcache, ARM_FPS_REGNUM,
77 (char *) &fparegset->fpr_fpsr);
81 fetch_register (int regno)
83 struct reg inferior_registers;
86 ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
87 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
91 warning ("unable to fetch general register");
98 regcache_raw_supply (current_regcache, ARM_SP_REGNUM,
99 (char *) &inferior_registers.r_sp);
103 regcache_raw_supply (current_regcache, ARM_LR_REGNUM,
104 (char *) &inferior_registers.r_lr);
108 /* This is ok: we're running native... */
109 inferior_registers.r_pc = ADDR_BITS_REMOVE (inferior_registers.r_pc);
110 regcache_raw_supply (current_regcache, ARM_PC_REGNUM,
111 (char *) &inferior_registers.r_pc);
116 regcache_raw_supply (current_regcache, ARM_PS_REGNUM,
117 (char *) &inferior_registers.r_cpsr);
119 regcache_raw_supply (current_regcache, ARM_PS_REGNUM,
120 (char *) &inferior_registers.r_pc);
124 regcache_raw_supply (current_regcache, regno,
125 (char *) &inferior_registers.r[regno]);
133 struct reg inferior_registers;
137 ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
138 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
142 warning ("unable to fetch general registers");
146 supply_gregset (&inferior_registers);
150 fetch_fp_register (int regno)
152 struct fpreg inferior_fp_registers;
155 ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
156 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
160 warning ("unable to fetch floating-point register");
167 regcache_raw_supply (current_regcache, ARM_FPS_REGNUM,
168 (char *) &inferior_fp_registers.fpr_fpsr);
172 regcache_raw_supply (current_regcache, regno,
173 (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
181 struct fpreg inferior_fp_registers;
185 ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
186 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
190 warning ("unable to fetch general registers");
194 supply_fparegset (&inferior_fp_registers);
198 fetch_inferior_registers (int regno)
202 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
203 fetch_register (regno);
205 fetch_fp_register (regno);
216 store_register (int regno)
218 struct reg inferior_registers;
221 ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
222 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
226 warning ("unable to fetch general registers");
233 regcache_raw_collect (current_regcache, ARM_SP_REGNUM,
234 (char *) &inferior_registers.r_sp);
238 regcache_raw_collect (current_regcache, ARM_LR_REGNUM,
239 (char *) &inferior_registers.r_lr);
244 regcache_raw_collect (current_regcache, ARM_PC_REGNUM,
245 (char *) &inferior_registers.r_pc);
250 regcache_raw_collect (current_regcache, ARM_PC_REGNUM,
253 pc_val = ADDR_BITS_REMOVE (pc_val);
254 inferior_registers.r_pc
255 ^= ADDR_BITS_REMOVE (inferior_registers.r_pc);
256 inferior_registers.r_pc |= pc_val;
262 regcache_raw_collect (current_regcache, ARM_PS_REGNUM,
263 (char *) &inferior_registers.r_cpsr);
268 regcache_raw_collect (current_regcache, ARM_PS_REGNUM,
271 psr_val ^= ADDR_BITS_REMOVE (psr_val);
272 inferior_registers.r_pc = ADDR_BITS_REMOVE (inferior_registers.r_pc);
273 inferior_registers.r_pc |= psr_val;
278 regcache_raw_collect (current_regcache, regno,
279 (char *) &inferior_registers.r[regno]);
283 ret = ptrace (PT_SETREGS, PIDGET (inferior_ptid),
284 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
287 warning ("unable to write register %d to inferior", regno);
293 struct reg inferior_registers;
298 for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
299 regcache_raw_collect (current_regcache, regno,
300 (char *) &inferior_registers.r[regno]);
302 regcache_raw_collect (current_regcache, ARM_SP_REGNUM,
303 (char *) &inferior_registers.r_sp);
304 regcache_raw_collect (current_regcache, ARM_LR_REGNUM,
305 (char *) &inferior_registers.r_lr);
309 regcache_raw_collect (current_regcache, ARM_PC_REGNUM,
310 (char *) &inferior_registers.r_pc);
311 regcache_raw_collect (current_regcache, ARM_PS_REGNUM,
312 (char *) &inferior_registers.r_cpsr);
319 regcache_raw_collect (current_regcache, ARM_PC_REGNUM,
321 regcache_raw_collect (current_regcache, ARM_PS_REGNUM,
324 pc_val = ADDR_BITS_REMOVE (pc_val);
325 psr_val ^= ADDR_BITS_REMOVE (psr_val);
327 inferior_registers.r_pc = pc_val | psr_val;
330 ret = ptrace (PT_SETREGS, PIDGET (inferior_ptid),
331 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
334 warning ("unable to store general registers");
338 store_fp_register (int regno)
340 struct fpreg inferior_fp_registers;
343 ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
344 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
348 warning ("unable to fetch floating-point registers");
355 regcache_raw_collect (current_regcache, ARM_FPS_REGNUM,
356 (char *) &inferior_fp_registers.fpr_fpsr);
360 regcache_raw_collect (current_regcache, regno,
361 (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
365 ret = ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
366 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
369 warning ("unable to write register %d to inferior", regno);
375 struct fpreg inferior_fp_registers;
380 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
381 regcache_raw_collect (current_regcache, regno,
382 (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
384 regcache_raw_collect (current_regcache, ARM_FPS_REGNUM,
385 (char *) &inferior_fp_registers.fpr_fpsr);
387 ret = ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
388 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
391 warning ("unable to store floating-point registers");
395 store_inferior_registers (int regno)
399 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
400 store_register (regno);
402 store_fp_register (regno);
418 fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
419 int which, CORE_ADDR ignore)
421 struct md_core *core_reg = (struct md_core *) core_reg_sect;
425 supply_gregset (&core_reg->intreg);
426 supply_fparegset (&core_reg->freg);
430 fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size,
431 int which, CORE_ADDR ignore)
434 struct fpreg fparegset;
438 case 0: /* Integer registers. */
439 if (core_reg_size != sizeof (struct reg))
440 warning ("wrong size of register set in core file");
443 /* The memcpy may be unnecessary, but we can't really be sure
444 of the alignment of the data in the core file. */
445 memcpy (&gregset, core_reg_sect, sizeof (gregset));
446 supply_gregset (&gregset);
451 if (core_reg_size != sizeof (struct fpreg))
452 warning ("wrong size of FPA register set in core file");
455 /* The memcpy may be unnecessary, but we can't really be sure
456 of the alignment of the data in the core file. */
457 memcpy (&fparegset, core_reg_sect, sizeof (fparegset));
458 supply_fparegset (&fparegset);
463 /* Don't know what kind of register request this is; just ignore it. */
468 static struct core_fns arm_netbsd_core_fns =
470 bfd_target_unknown_flavour, /* core_flovour. */
471 default_check_format, /* check_format. */
472 default_core_sniffer, /* core_sniffer. */
473 fetch_core_registers, /* core_read_registers. */
477 static struct core_fns arm_netbsd_elfcore_fns =
479 bfd_target_elf_flavour, /* core_flovour. */
480 default_check_format, /* check_format. */
481 default_core_sniffer, /* core_sniffer. */
482 fetch_elfcore_registers, /* core_read_registers. */
487 _initialize_arm_netbsd_nat (void)
489 deprecated_add_core_fns (&arm_netbsd_core_fns);
490 deprecated_add_core_fns (&arm_netbsd_elfcore_fns);