1 /* Native-dependent code for BSD Unix running on ARM's, for GDB.
3 Copyright (C) 1988-2019 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/>. */
22 /* Standard C includes. */
23 #include <machine/frame.h>
24 #include <machine/reg.h>
25 #include <sys/ptrace.h>
26 #include <sys/types.h>
28 /* Local non-gdb includes. */
31 #include "inf-ptrace.h"
36 class arm_netbsd_nat_target final
: public inf_ptrace_target
39 /* Add our register access methods. */
40 void fetch_registers (struct regcache
*, int) override
;
41 void store_registers (struct regcache
*, int) override
;
44 static arm_netbsd_nat_target the_arm_netbsd_nat_target
;
46 extern int arm_apcs_32
;
49 arm_supply_gregset (struct regcache
*regcache
, struct reg
*gregset
)
54 /* Integer registers. */
55 for (regno
= ARM_A1_REGNUM
; regno
< ARM_SP_REGNUM
; regno
++)
56 regcache
->raw_supply (regno
, (char *) &gregset
->r
[regno
]);
58 regcache
->raw_supply (ARM_SP_REGNUM
, (char *) &gregset
->r_sp
);
59 regcache
->raw_supply (ARM_LR_REGNUM
, (char *) &gregset
->r_lr
);
60 /* This is ok: we're running native... */
61 r_pc
= gdbarch_addr_bits_remove (regcache
->arch (), gregset
->r_pc
);
62 regcache
->raw_supply (ARM_PC_REGNUM
, (char *) &r_pc
);
65 regcache
->raw_supply (ARM_PS_REGNUM
, (char *) &gregset
->r_cpsr
);
67 regcache
->raw_supply (ARM_PS_REGNUM
, (char *) &gregset
->r_pc
);
71 arm_supply_fparegset (struct regcache
*regcache
, struct fpreg
*fparegset
)
75 for (regno
= ARM_F0_REGNUM
; regno
<= ARM_F7_REGNUM
; regno
++)
76 regcache
->raw_supply (regno
,
77 (char *) &fparegset
->fpr
[regno
- ARM_F0_REGNUM
]);
79 regcache
->raw_supply (ARM_FPS_REGNUM
, (char *) &fparegset
->fpr_fpsr
);
83 fetch_register (struct regcache
*regcache
, int regno
)
85 struct reg inferior_registers
;
88 ret
= ptrace (PT_GETREGS
, regcache
->ptid ().pid (),
89 (PTRACE_TYPE_ARG3
) &inferior_registers
, 0);
93 warning (_("unable to fetch general register"));
100 regcache
->raw_supply (ARM_SP_REGNUM
, (char *) &inferior_registers
.r_sp
);
104 regcache
->raw_supply (ARM_LR_REGNUM
, (char *) &inferior_registers
.r_lr
);
108 /* This is ok: we're running native... */
109 inferior_registers
.r_pc
= gdbarch_addr_bits_remove
111 inferior_registers
.r_pc
);
112 regcache
->raw_supply (ARM_PC_REGNUM
, (char *) &inferior_registers
.r_pc
);
117 regcache
->raw_supply (ARM_PS_REGNUM
,
118 (char *) &inferior_registers
.r_cpsr
);
120 regcache
->raw_supply (ARM_PS_REGNUM
,
121 (char *) &inferior_registers
.r_pc
);
125 regcache
->raw_supply (regno
, (char *) &inferior_registers
.r
[regno
]);
131 fetch_regs (struct regcache
*regcache
)
133 struct reg inferior_registers
;
137 ret
= ptrace (PT_GETREGS
, regcache
->ptid ().pid (),
138 (PTRACE_TYPE_ARG3
) &inferior_registers
, 0);
142 warning (_("unable to fetch general registers"));
146 arm_supply_gregset (regcache
, &inferior_registers
);
150 fetch_fp_register (struct regcache
*regcache
, int regno
)
152 struct fpreg inferior_fp_registers
;
155 ret
= ptrace (PT_GETFPREGS
, regcache
->ptid ().pid (),
156 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, 0);
160 warning (_("unable to fetch floating-point register"));
167 regcache
->raw_supply (ARM_FPS_REGNUM
,
168 (char *) &inferior_fp_registers
.fpr_fpsr
);
173 (regno
, (char *) &inferior_fp_registers
.fpr
[regno
- ARM_F0_REGNUM
]);
179 fetch_fp_regs (struct regcache
*regcache
)
181 struct fpreg inferior_fp_registers
;
185 ret
= ptrace (PT_GETFPREGS
, regcache
->ptid ().pid (),
186 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, 0);
190 warning (_("unable to fetch general registers"));
194 arm_supply_fparegset (regcache
, &inferior_fp_registers
);
198 arm_nbsd_nat_target::fetch_registers (struct regcache
*regcache
, int regno
)
202 if (regno
< ARM_F0_REGNUM
|| regno
> ARM_FPS_REGNUM
)
203 fetch_register (regcache
, regno
);
205 fetch_fp_register (regcache
, regno
);
209 fetch_regs (regcache
);
210 fetch_fp_regs (regcache
);
216 store_register (const struct regcache
*regcache
, int regno
)
218 struct gdbarch
*gdbarch
= regcache
->arch ();
219 struct reg inferior_registers
;
222 ret
= ptrace (PT_GETREGS
, regcache
->ptid ().pid (),
223 (PTRACE_TYPE_ARG3
) &inferior_registers
, 0);
227 warning (_("unable to fetch general registers"));
234 regcache
->raw_collect (ARM_SP_REGNUM
, (char *) &inferior_registers
.r_sp
);
238 regcache
->raw_collect (ARM_LR_REGNUM
, (char *) &inferior_registers
.r_lr
);
243 regcache
->raw_collect (ARM_PC_REGNUM
,
244 (char *) &inferior_registers
.r_pc
);
249 regcache
->raw_collect (ARM_PC_REGNUM
, (char *) &pc_val
);
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 (ARM_PS_REGNUM
,
261 (char *) &inferior_registers
.r_cpsr
);
266 regcache
->raw_collect (ARM_PS_REGNUM
, (char *) &psr_val
);
268 psr_val
^= gdbarch_addr_bits_remove (gdbarch
, psr_val
);
269 inferior_registers
.r_pc
= gdbarch_addr_bits_remove
270 (gdbarch
, inferior_registers
.r_pc
);
271 inferior_registers
.r_pc
|= psr_val
;
276 regcache
->raw_collect (regno
, (char *) &inferior_registers
.r
[regno
]);
280 ret
= ptrace (PT_SETREGS
, regcache
->ptid ().pid (),
281 (PTRACE_TYPE_ARG3
) &inferior_registers
, 0);
284 warning (_("unable to write register %d to inferior"), regno
);
288 store_regs (const struct regcache
*regcache
)
290 struct gdbarch
*gdbarch
= regcache
->arch ();
291 struct reg inferior_registers
;
296 for (regno
= ARM_A1_REGNUM
; regno
< ARM_SP_REGNUM
; regno
++)
297 regcache
->raw_collect (regno
, (char *) &inferior_registers
.r
[regno
]);
299 regcache
->raw_collect (ARM_SP_REGNUM
, (char *) &inferior_registers
.r_sp
);
300 regcache
->raw_collect (ARM_LR_REGNUM
, (char *) &inferior_registers
.r_lr
);
304 regcache
->raw_collect (ARM_PC_REGNUM
, (char *) &inferior_registers
.r_pc
);
305 regcache
->raw_collect (ARM_PS_REGNUM
,
306 (char *) &inferior_registers
.r_cpsr
);
313 regcache
->raw_collect (ARM_PC_REGNUM
, (char *) &pc_val
);
314 regcache
->raw_collect (ARM_PS_REGNUM
, (char *) &psr_val
);
316 pc_val
= gdbarch_addr_bits_remove (gdbarch
, pc_val
);
317 psr_val
^= gdbarch_addr_bits_remove (gdbarch
, psr_val
);
319 inferior_registers
.r_pc
= pc_val
| psr_val
;
322 ret
= ptrace (PT_SETREGS
, regcache
->ptid ().pid (),
323 (PTRACE_TYPE_ARG3
) &inferior_registers
, 0);
326 warning (_("unable to store general registers"));
330 store_fp_register (const struct regcache
*regcache
, int regno
)
332 struct fpreg inferior_fp_registers
;
335 ret
= ptrace (PT_GETFPREGS
, regcache
->ptid ().pid (),
336 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, 0);
340 warning (_("unable to fetch floating-point registers"));
347 regcache
->raw_collect (ARM_FPS_REGNUM
,
348 (char *) &inferior_fp_registers
.fpr_fpsr
);
352 regcache
->raw_collect
353 (regno
, (char *) &inferior_fp_registers
.fpr
[regno
- ARM_F0_REGNUM
]);
357 ret
= ptrace (PT_SETFPREGS
, regcache
->ptid ().pid (),
358 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, 0);
361 warning (_("unable to write register %d to inferior"), regno
);
365 store_fp_regs (const struct regcache
*regcache
)
367 struct fpreg inferior_fp_registers
;
372 for (regno
= ARM_F0_REGNUM
; regno
<= ARM_F7_REGNUM
; regno
++)
373 regcache
->raw_collect
374 (regno
, (char *) &inferior_fp_registers
.fpr
[regno
- ARM_F0_REGNUM
]);
376 regcache
->raw_collect (ARM_FPS_REGNUM
,
377 (char *) &inferior_fp_registers
.fpr_fpsr
);
379 ret
= ptrace (PT_SETFPREGS
, regcache
->ptid ().pid (),
380 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, 0);
383 warning (_("unable to store floating-point registers"));
387 arm_nbsd_nat_target::store_registers (struct regcache
*regcache
, int regno
)
391 if (regno
< ARM_F0_REGNUM
|| regno
> ARM_FPS_REGNUM
)
392 store_register (regcache
, regno
);
394 store_fp_register (regcache
, regno
);
398 store_regs (regcache
);
399 store_fp_regs (regcache
);
404 fetch_elfcore_registers (struct regcache
*regcache
,
405 char *core_reg_sect
, unsigned core_reg_size
,
406 int which
, CORE_ADDR ignore
)
409 struct fpreg fparegset
;
413 case 0: /* Integer registers. */
414 if (core_reg_size
!= sizeof (struct reg
))
415 warning (_("wrong size of register set in core file"));
418 /* The memcpy may be unnecessary, but we can't really be sure
419 of the alignment of the data in the core file. */
420 memcpy (&gregset
, core_reg_sect
, sizeof (gregset
));
421 arm_supply_gregset (regcache
, &gregset
);
426 if (core_reg_size
!= sizeof (struct fpreg
))
427 warning (_("wrong size of FPA register set in core file"));
430 /* The memcpy may be unnecessary, but we can't really be sure
431 of the alignment of the data in the core file. */
432 memcpy (&fparegset
, core_reg_sect
, sizeof (fparegset
));
433 arm_supply_fparegset (regcache
, &fparegset
);
438 /* Don't know what kind of register request this is; just ignore it. */
443 static struct core_fns arm_netbsd_elfcore_fns
=
445 bfd_target_elf_flavour
, /* core_flovour. */
446 default_check_format
, /* check_format. */
447 default_core_sniffer
, /* core_sniffer. */
448 fetch_elfcore_registers
, /* core_read_registers. */
453 _initialize_arm_netbsd_nat (void)
455 add_inf_child_target (&the_arm_netbsd_nat_target
);
457 deprecated_add_core_fns (&arm_netbsd_elfcore_fns
);