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 (regno
, (char *) &gregset
->r
[regno
]);
55 regcache
->raw_supply (ARM_SP_REGNUM
, (char *) &gregset
->r_sp
);
56 regcache
->raw_supply (ARM_LR_REGNUM
, (char *) &gregset
->r_lr
);
57 /* This is ok: we're running native... */
58 r_pc
= gdbarch_addr_bits_remove (regcache
->arch (), gregset
->r_pc
);
59 regcache
->raw_supply (ARM_PC_REGNUM
, (char *) &r_pc
);
62 regcache
->raw_supply (ARM_PS_REGNUM
, (char *) &gregset
->r_cpsr
);
64 regcache
->raw_supply (ARM_PS_REGNUM
, (char *) &gregset
->r_pc
);
68 arm_supply_fparegset (struct regcache
*regcache
, struct fpreg
*fparegset
)
72 for (regno
= ARM_F0_REGNUM
; regno
<= ARM_F7_REGNUM
; regno
++)
73 regcache
->raw_supply (regno
,
74 (char *) &fparegset
->fpr
[regno
- ARM_F0_REGNUM
]);
76 regcache
->raw_supply (ARM_FPS_REGNUM
, (char *) &fparegset
->fpr_fpsr
);
80 fetch_register (struct regcache
*regcache
, int regno
)
82 struct reg inferior_registers
;
85 ret
= ptrace (PT_GETREGS
, ptid_get_pid (regcache
->ptid ()),
86 (PTRACE_TYPE_ARG3
) &inferior_registers
, 0);
90 warning (_("unable to fetch general register"));
97 regcache
->raw_supply (ARM_SP_REGNUM
, (char *) &inferior_registers
.r_sp
);
101 regcache
->raw_supply (ARM_LR_REGNUM
, (char *) &inferior_registers
.r_lr
);
105 /* This is ok: we're running native... */
106 inferior_registers
.r_pc
= gdbarch_addr_bits_remove
108 inferior_registers
.r_pc
);
109 regcache
->raw_supply (ARM_PC_REGNUM
, (char *) &inferior_registers
.r_pc
);
114 regcache
->raw_supply (ARM_PS_REGNUM
,
115 (char *) &inferior_registers
.r_cpsr
);
117 regcache
->raw_supply (ARM_PS_REGNUM
,
118 (char *) &inferior_registers
.r_pc
);
122 regcache
->raw_supply (regno
, (char *) &inferior_registers
.r
[regno
]);
128 fetch_regs (struct regcache
*regcache
)
130 struct reg inferior_registers
;
134 ret
= ptrace (PT_GETREGS
, ptid_get_pid (regcache
->ptid ()),
135 (PTRACE_TYPE_ARG3
) &inferior_registers
, 0);
139 warning (_("unable to fetch general registers"));
143 arm_supply_gregset (regcache
, &inferior_registers
);
147 fetch_fp_register (struct regcache
*regcache
, int regno
)
149 struct fpreg inferior_fp_registers
;
152 ret
= ptrace (PT_GETFPREGS
, ptid_get_pid (regcache
->ptid ()),
153 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, 0);
157 warning (_("unable to fetch floating-point register"));
164 regcache
->raw_supply (ARM_FPS_REGNUM
,
165 (char *) &inferior_fp_registers
.fpr_fpsr
);
170 (regno
, (char *) &inferior_fp_registers
.fpr
[regno
- ARM_F0_REGNUM
]);
176 fetch_fp_regs (struct regcache
*regcache
)
178 struct fpreg inferior_fp_registers
;
182 ret
= ptrace (PT_GETFPREGS
, ptid_get_pid (regcache
->ptid ()),
183 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, 0);
187 warning (_("unable to fetch general registers"));
191 arm_supply_fparegset (regcache
, &inferior_fp_registers
);
195 arm_nbsd_nat_target::fetch_registers (struct regcache
*regcache
, int regno
)
199 if (regno
< ARM_F0_REGNUM
|| regno
> ARM_FPS_REGNUM
)
200 fetch_register (regcache
, regno
);
202 fetch_fp_register (regcache
, regno
);
206 fetch_regs (regcache
);
207 fetch_fp_regs (regcache
);
213 store_register (const struct regcache
*regcache
, int regno
)
215 struct gdbarch
*gdbarch
= regcache
->arch ();
216 struct reg inferior_registers
;
219 ret
= ptrace (PT_GETREGS
, ptid_get_pid (regcache
->ptid ()),
220 (PTRACE_TYPE_ARG3
) &inferior_registers
, 0);
224 warning (_("unable to fetch general registers"));
231 regcache_raw_collect (regcache
, ARM_SP_REGNUM
,
232 (char *) &inferior_registers
.r_sp
);
236 regcache_raw_collect (regcache
, ARM_LR_REGNUM
,
237 (char *) &inferior_registers
.r_lr
);
242 regcache_raw_collect (regcache
, ARM_PC_REGNUM
,
243 (char *) &inferior_registers
.r_pc
);
248 regcache_raw_collect (regcache
, ARM_PC_REGNUM
,
251 pc_val
= gdbarch_addr_bits_remove (gdbarch
, pc_val
);
252 inferior_registers
.r_pc
^= gdbarch_addr_bits_remove
253 (gdbarch
, inferior_registers
.r_pc
);
254 inferior_registers
.r_pc
|= pc_val
;
260 regcache_raw_collect (regcache
, ARM_PS_REGNUM
,
261 (char *) &inferior_registers
.r_cpsr
);
266 regcache_raw_collect (regcache
, ARM_PS_REGNUM
,
269 psr_val
^= gdbarch_addr_bits_remove (gdbarch
, psr_val
);
270 inferior_registers
.r_pc
= gdbarch_addr_bits_remove
271 (gdbarch
, inferior_registers
.r_pc
);
272 inferior_registers
.r_pc
|= psr_val
;
277 regcache_raw_collect (regcache
, regno
,
278 (char *) &inferior_registers
.r
[regno
]);
282 ret
= ptrace (PT_SETREGS
, ptid_get_pid (regcache
->ptid ()),
283 (PTRACE_TYPE_ARG3
) &inferior_registers
, 0);
286 warning (_("unable to write register %d to inferior"), regno
);
290 store_regs (const struct regcache
*regcache
)
292 struct gdbarch
*gdbarch
= regcache
->arch ();
293 struct reg inferior_registers
;
298 for (regno
= ARM_A1_REGNUM
; regno
< ARM_SP_REGNUM
; regno
++)
299 regcache_raw_collect (regcache
, regno
,
300 (char *) &inferior_registers
.r
[regno
]);
302 regcache_raw_collect (regcache
, ARM_SP_REGNUM
,
303 (char *) &inferior_registers
.r_sp
);
304 regcache_raw_collect (regcache
, ARM_LR_REGNUM
,
305 (char *) &inferior_registers
.r_lr
);
309 regcache_raw_collect (regcache
, ARM_PC_REGNUM
,
310 (char *) &inferior_registers
.r_pc
);
311 regcache_raw_collect (regcache
, ARM_PS_REGNUM
,
312 (char *) &inferior_registers
.r_cpsr
);
319 regcache_raw_collect (regcache
, ARM_PC_REGNUM
,
321 regcache_raw_collect (regcache
, ARM_PS_REGNUM
,
324 pc_val
= gdbarch_addr_bits_remove (gdbarch
, pc_val
);
325 psr_val
^= gdbarch_addr_bits_remove (gdbarch
, psr_val
);
327 inferior_registers
.r_pc
= pc_val
| psr_val
;
330 ret
= ptrace (PT_SETREGS
, ptid_get_pid (regcache
->ptid ()),
331 (PTRACE_TYPE_ARG3
) &inferior_registers
, 0);
334 warning (_("unable to store general registers"));
338 store_fp_register (const struct regcache
*regcache
, int regno
)
340 struct fpreg inferior_fp_registers
;
343 ret
= ptrace (PT_GETFPREGS
, ptid_get_pid (regcache
->ptid ()),
344 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, 0);
348 warning (_("unable to fetch floating-point registers"));
355 regcache_raw_collect (regcache
, ARM_FPS_REGNUM
,
356 (char *) &inferior_fp_registers
.fpr_fpsr
);
360 regcache_raw_collect (regcache
, regno
,
361 (char *) &inferior_fp_registers
.fpr
[regno
- ARM_F0_REGNUM
]);
365 ret
= ptrace (PT_SETFPREGS
, ptid_get_pid (regcache
->ptid ()),
366 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, 0);
369 warning (_("unable to write register %d to inferior"), regno
);
373 store_fp_regs (const struct regcache
*regcache
)
375 struct fpreg inferior_fp_registers
;
380 for (regno
= ARM_F0_REGNUM
; regno
<= ARM_F7_REGNUM
; regno
++)
381 regcache_raw_collect (regcache
, regno
,
382 (char *) &inferior_fp_registers
.fpr
[regno
- ARM_F0_REGNUM
]);
384 regcache_raw_collect (regcache
, ARM_FPS_REGNUM
,
385 (char *) &inferior_fp_registers
.fpr_fpsr
);
387 ret
= ptrace (PT_SETFPREGS
, ptid_get_pid (regcache
->ptid ()),
388 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, 0);
391 warning (_("unable to store floating-point registers"));
395 arm_nbsd_nat_target::store_registers (struct regcache
*regcache
, int regno
)
399 if (regno
< ARM_F0_REGNUM
|| regno
> ARM_FPS_REGNUM
)
400 store_register (regcache
, regno
);
402 store_fp_register (regcache
, regno
);
406 store_regs (regcache
);
407 store_fp_regs (regcache
);
412 fetch_elfcore_registers (struct regcache
*regcache
,
413 char *core_reg_sect
, unsigned core_reg_size
,
414 int which
, CORE_ADDR ignore
)
417 struct fpreg fparegset
;
421 case 0: /* Integer registers. */
422 if (core_reg_size
!= sizeof (struct reg
))
423 warning (_("wrong size of register set in core file"));
426 /* The memcpy may be unnecessary, but we can't really be sure
427 of the alignment of the data in the core file. */
428 memcpy (&gregset
, core_reg_sect
, sizeof (gregset
));
429 arm_supply_gregset (regcache
, &gregset
);
434 if (core_reg_size
!= sizeof (struct fpreg
))
435 warning (_("wrong size of FPA register set in core file"));
438 /* The memcpy may be unnecessary, but we can't really be sure
439 of the alignment of the data in the core file. */
440 memcpy (&fparegset
, core_reg_sect
, sizeof (fparegset
));
441 arm_supply_fparegset (regcache
, &fparegset
);
446 /* Don't know what kind of register request this is; just ignore it. */
451 static struct core_fns arm_netbsd_elfcore_fns
=
453 bfd_target_elf_flavour
, /* core_flovour. */
454 default_check_format
, /* check_format. */
455 default_core_sniffer
, /* core_sniffer. */
456 fetch_elfcore_registers
, /* core_read_registers. */
461 _initialize_arm_netbsd_nat (void)
463 add_inf_child_target (&the_arm_netbsd_nat_target
);
465 deprecated_add_core_fns (&arm_netbsd_elfcore_fns
);