1 /* Native-dependent code for BSD Unix running on ARM's, for GDB.
3 Copyright (C) 1988-2018 Free Software Foundation, Inc.
5 This file is part of GDB.
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 3 of the License, or
10 (at your option) any later version.
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.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
25 #include <sys/types.h>
26 #include <sys/ptrace.h>
27 #include <machine/reg.h>
28 #include <machine/frame.h>
31 #include "inf-ptrace.h"
33 class arm_netbsd_nat_target final : public inf_ptrace_target
36 /* Add our register access methods. */
37 void fetch_registers (struct regcache *, int) override;
38 void store_registers (struct regcache *, int) override;
41 static arm_netbsd_nat_target the_arm_netbsd_nat_target;
43 extern int arm_apcs_32;
46 arm_supply_gregset (struct regcache *regcache, struct reg *gregset)
51 /* Integer registers. */
52 for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
53 regcache_raw_supply (regcache, regno, (char *) &gregset->r[regno]);
55 regcache_raw_supply (regcache, ARM_SP_REGNUM,
56 (char *) &gregset->r_sp);
57 regcache_raw_supply (regcache, ARM_LR_REGNUM,
58 (char *) &gregset->r_lr);
59 /* This is ok: we're running native... */
60 r_pc = gdbarch_addr_bits_remove (regcache->arch (), gregset->r_pc);
61 regcache_raw_supply (regcache, ARM_PC_REGNUM, (char *) &r_pc);
64 regcache_raw_supply (regcache, ARM_PS_REGNUM,
65 (char *) &gregset->r_cpsr);
67 regcache_raw_supply (regcache, ARM_PS_REGNUM,
68 (char *) &gregset->r_pc);
72 arm_supply_fparegset (struct regcache *regcache, struct fpreg *fparegset)
76 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
77 regcache_raw_supply (regcache, regno,
78 (char *) &fparegset->fpr[regno - ARM_F0_REGNUM]);
80 regcache_raw_supply (regcache, ARM_FPS_REGNUM,
81 (char *) &fparegset->fpr_fpsr);
85 fetch_register (struct regcache *regcache, int regno)
87 struct reg inferior_registers;
90 ret = ptrace (PT_GETREGS, ptid_get_pid (regcache_get_ptid (regcache)),
91 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
95 warning (_("unable to fetch general register"));
102 regcache_raw_supply (regcache, ARM_SP_REGNUM,
103 (char *) &inferior_registers.r_sp);
107 regcache_raw_supply (regcache, ARM_LR_REGNUM,
108 (char *) &inferior_registers.r_lr);
112 /* This is ok: we're running native... */
113 inferior_registers.r_pc = gdbarch_addr_bits_remove
115 inferior_registers.r_pc);
116 regcache_raw_supply (regcache, ARM_PC_REGNUM,
117 (char *) &inferior_registers.r_pc);
122 regcache_raw_supply (regcache, ARM_PS_REGNUM,
123 (char *) &inferior_registers.r_cpsr);
125 regcache_raw_supply (regcache, ARM_PS_REGNUM,
126 (char *) &inferior_registers.r_pc);
130 regcache_raw_supply (regcache, regno,
131 (char *) &inferior_registers.r[regno]);
137 fetch_regs (struct regcache *regcache)
139 struct reg inferior_registers;
143 ret = ptrace (PT_GETREGS, ptid_get_pid (regcache_get_ptid (regcache)),
144 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
148 warning (_("unable to fetch general registers"));
152 arm_supply_gregset (regcache, &inferior_registers);
156 fetch_fp_register (struct regcache *regcache, int regno)
158 struct fpreg inferior_fp_registers;
161 ret = ptrace (PT_GETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)),
162 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
166 warning (_("unable to fetch floating-point register"));
173 regcache_raw_supply (regcache, ARM_FPS_REGNUM,
174 (char *) &inferior_fp_registers.fpr_fpsr);
178 regcache_raw_supply (regcache, regno,
179 (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
185 fetch_fp_regs (struct regcache *regcache)
187 struct fpreg inferior_fp_registers;
191 ret = ptrace (PT_GETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)),
192 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
196 warning (_("unable to fetch general registers"));
200 arm_supply_fparegset (regcache, &inferior_fp_registers);
204 arm_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
208 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
209 fetch_register (regcache, regno);
211 fetch_fp_register (regcache, regno);
215 fetch_regs (regcache);
216 fetch_fp_regs (regcache);
222 store_register (const struct regcache *regcache, int regno)
224 struct gdbarch *gdbarch = regcache->arch ();
225 struct reg inferior_registers;
228 ret = ptrace (PT_GETREGS, ptid_get_pid (regcache_get_ptid (regcache)),
229 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
233 warning (_("unable to fetch general registers"));
240 regcache_raw_collect (regcache, ARM_SP_REGNUM,
241 (char *) &inferior_registers.r_sp);
245 regcache_raw_collect (regcache, ARM_LR_REGNUM,
246 (char *) &inferior_registers.r_lr);
251 regcache_raw_collect (regcache, ARM_PC_REGNUM,
252 (char *) &inferior_registers.r_pc);
257 regcache_raw_collect (regcache, ARM_PC_REGNUM,
260 pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
261 inferior_registers.r_pc ^= gdbarch_addr_bits_remove
262 (gdbarch, inferior_registers.r_pc);
263 inferior_registers.r_pc |= pc_val;
269 regcache_raw_collect (regcache, ARM_PS_REGNUM,
270 (char *) &inferior_registers.r_cpsr);
275 regcache_raw_collect (regcache, ARM_PS_REGNUM,
278 psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
279 inferior_registers.r_pc = gdbarch_addr_bits_remove
280 (gdbarch, inferior_registers.r_pc);
281 inferior_registers.r_pc |= psr_val;
286 regcache_raw_collect (regcache, regno,
287 (char *) &inferior_registers.r[regno]);
291 ret = ptrace (PT_SETREGS, ptid_get_pid (regcache_get_ptid (regcache)),
292 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
295 warning (_("unable to write register %d to inferior"), regno);
299 store_regs (const struct regcache *regcache)
301 struct gdbarch *gdbarch = regcache->arch ();
302 struct reg inferior_registers;
307 for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
308 regcache_raw_collect (regcache, regno,
309 (char *) &inferior_registers.r[regno]);
311 regcache_raw_collect (regcache, ARM_SP_REGNUM,
312 (char *) &inferior_registers.r_sp);
313 regcache_raw_collect (regcache, ARM_LR_REGNUM,
314 (char *) &inferior_registers.r_lr);
318 regcache_raw_collect (regcache, ARM_PC_REGNUM,
319 (char *) &inferior_registers.r_pc);
320 regcache_raw_collect (regcache, ARM_PS_REGNUM,
321 (char *) &inferior_registers.r_cpsr);
328 regcache_raw_collect (regcache, ARM_PC_REGNUM,
330 regcache_raw_collect (regcache, ARM_PS_REGNUM,
333 pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
334 psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
336 inferior_registers.r_pc = pc_val | psr_val;
339 ret = ptrace (PT_SETREGS, ptid_get_pid (regcache_get_ptid (regcache)),
340 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
343 warning (_("unable to store general registers"));
347 store_fp_register (const struct regcache *regcache, int regno)
349 struct fpreg inferior_fp_registers;
352 ret = ptrace (PT_GETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)),
353 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
357 warning (_("unable to fetch floating-point registers"));
364 regcache_raw_collect (regcache, ARM_FPS_REGNUM,
365 (char *) &inferior_fp_registers.fpr_fpsr);
369 regcache_raw_collect (regcache, regno,
370 (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
374 ret = ptrace (PT_SETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)),
375 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
378 warning (_("unable to write register %d to inferior"), regno);
382 store_fp_regs (const struct regcache *regcache)
384 struct fpreg inferior_fp_registers;
389 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
390 regcache_raw_collect (regcache, regno,
391 (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
393 regcache_raw_collect (regcache, ARM_FPS_REGNUM,
394 (char *) &inferior_fp_registers.fpr_fpsr);
396 ret = ptrace (PT_SETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)),
397 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
400 warning (_("unable to store floating-point registers"));
404 arm_nbsd_nat_target::store_registers (struct regcache *regcache, int regno)
408 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
409 store_register (regcache, regno);
411 store_fp_register (regcache, regno);
415 store_regs (regcache);
416 store_fp_regs (regcache);
421 fetch_elfcore_registers (struct regcache *regcache,
422 char *core_reg_sect, unsigned core_reg_size,
423 int which, CORE_ADDR ignore)
426 struct fpreg fparegset;
430 case 0: /* Integer registers. */
431 if (core_reg_size != sizeof (struct reg))
432 warning (_("wrong size of register set in core file"));
435 /* The memcpy may be unnecessary, but we can't really be sure
436 of the alignment of the data in the core file. */
437 memcpy (&gregset, core_reg_sect, sizeof (gregset));
438 arm_supply_gregset (regcache, &gregset);
443 if (core_reg_size != sizeof (struct fpreg))
444 warning (_("wrong size of FPA register set in core file"));
447 /* The memcpy may be unnecessary, but we can't really be sure
448 of the alignment of the data in the core file. */
449 memcpy (&fparegset, core_reg_sect, sizeof (fparegset));
450 arm_supply_fparegset (regcache, &fparegset);
455 /* Don't know what kind of register request this is; just ignore it. */
460 static struct core_fns arm_netbsd_elfcore_fns =
462 bfd_target_elf_flavour, /* core_flovour. */
463 default_check_format, /* check_format. */
464 default_core_sniffer, /* core_sniffer. */
465 fetch_elfcore_registers, /* core_read_registers. */
470 _initialize_arm_netbsd_nat (void)
472 add_target (&the_arm_netbsd_nat_target);
474 deprecated_add_core_fns (&arm_netbsd_elfcore_fns);