1 /* Native-dependent code for BSD Unix running on ARM's, for GDB.
3 Copyright (C) 1988-2020 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/>. */
20 /* We define this to get types like register_t. */
27 #include <sys/types.h>
28 #include <sys/ptrace.h>
29 #include <sys/sysctl.h>
30 #include <machine/reg.h>
31 #include <machine/frame.h>
34 #include "aarch32-tdep.h"
35 #include "inf-ptrace.h"
37 class arm_netbsd_nat_target final
: public inf_ptrace_target
40 /* Add our register access methods. */
41 void fetch_registers (struct regcache
*, int) override
;
42 void store_registers (struct regcache
*, int) override
;
43 const struct target_desc
*read_description () override
;
46 static arm_netbsd_nat_target the_arm_netbsd_nat_target
;
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_vfpregset (struct regcache
*regcache
, struct fpreg
*fpregset
)
73 struct gdbarch_tdep
*tdep
= gdbarch_tdep (regcache
->arch ());
74 if (tdep
->vfp_register_count
== 0)
77 struct vfpreg
&vfp
= fpregset
->fpr_vfp
;
78 for (int regno
= 0; regno
<= tdep
->vfp_register_count
; regno
++)
79 regcache
->raw_supply (regno
+ ARM_D0_REGNUM
, (char *) &vfp
.vfp_regs
[regno
]);
81 regcache
->raw_supply (ARM_FPSCR_REGNUM
, (char *) &vfp
.vfp_fpscr
);
85 fetch_register (struct regcache
*regcache
, int regno
)
87 struct reg inferior_registers
;
90 ret
= ptrace (PT_GETREGS
, regcache
->ptid ().pid (),
91 (PTRACE_TYPE_ARG3
) &inferior_registers
, 0);
95 warning (_("unable to fetch general register"));
102 regcache
->raw_supply (ARM_SP_REGNUM
, (char *) &inferior_registers
.r_sp
);
106 regcache
->raw_supply (ARM_LR_REGNUM
, (char *) &inferior_registers
.r_lr
);
110 /* This is ok: we're running native... */
111 inferior_registers
.r_pc
= gdbarch_addr_bits_remove
113 inferior_registers
.r_pc
);
114 regcache
->raw_supply (ARM_PC_REGNUM
, (char *) &inferior_registers
.r_pc
);
119 regcache
->raw_supply (ARM_PS_REGNUM
,
120 (char *) &inferior_registers
.r_cpsr
);
122 regcache
->raw_supply (ARM_PS_REGNUM
,
123 (char *) &inferior_registers
.r_pc
);
127 regcache
->raw_supply (regno
, (char *) &inferior_registers
.r
[regno
]);
133 fetch_regs (struct regcache
*regcache
)
135 struct reg inferior_registers
;
139 ret
= ptrace (PT_GETREGS
, regcache
->ptid ().pid (),
140 (PTRACE_TYPE_ARG3
) &inferior_registers
, 0);
144 warning (_("unable to fetch general registers"));
148 arm_supply_gregset (regcache
, &inferior_registers
);
152 fetch_fp_register (struct regcache
*regcache
, int regno
)
154 struct fpreg inferior_fp_registers
;
155 int ret
= ptrace (PT_GETFPREGS
, regcache
->ptid ().pid (),
156 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, 0);
158 struct vfpreg
&vfp
= inferior_fp_registers
.fpr_vfp
;
162 warning (_("unable to fetch floating-point register"));
166 struct gdbarch_tdep
*tdep
= gdbarch_tdep (regcache
->arch ());
167 if (regno
== ARM_FPSCR_REGNUM
&& tdep
->vfp_register_count
!= 0)
168 regcache
->raw_supply (ARM_FPSCR_REGNUM
, (char *) &vfp
.vfp_fpscr
);
169 else if (regno
>= ARM_D0_REGNUM
170 && regno
<= ARM_D0_REGNUM
+ tdep
->vfp_register_count
)
172 regcache
->raw_supply (regno
,
173 (char *) &vfp
.vfp_regs
[regno
- ARM_D0_REGNUM
]);
176 warning (_("Invalid register number."));
180 fetch_fp_regs (struct regcache
*regcache
)
182 struct fpreg inferior_fp_registers
;
186 ret
= ptrace (PT_GETFPREGS
, regcache
->ptid ().pid (),
187 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, 0);
191 warning (_("unable to fetch general registers"));
195 arm_supply_vfpregset (regcache
, &inferior_fp_registers
);
199 arm_netbsd_nat_target::fetch_registers (struct regcache
*regcache
, int regno
)
203 if (regno
< ARM_F0_REGNUM
|| regno
> ARM_FPS_REGNUM
)
204 fetch_register (regcache
, regno
);
206 fetch_fp_register (regcache
, regno
);
210 fetch_regs (regcache
);
211 fetch_fp_regs (regcache
);
217 store_register (const struct regcache
*regcache
, int regno
)
219 struct gdbarch
*gdbarch
= regcache
->arch ();
220 struct reg inferior_registers
;
223 ret
= ptrace (PT_GETREGS
, regcache
->ptid ().pid (),
224 (PTRACE_TYPE_ARG3
) &inferior_registers
, 0);
228 warning (_("unable to fetch general registers"));
235 regcache
->raw_collect (ARM_SP_REGNUM
, (char *) &inferior_registers
.r_sp
);
239 regcache
->raw_collect (ARM_LR_REGNUM
, (char *) &inferior_registers
.r_lr
);
244 regcache
->raw_collect (ARM_PC_REGNUM
,
245 (char *) &inferior_registers
.r_pc
);
250 regcache
->raw_collect (ARM_PC_REGNUM
, (char *) &pc_val
);
252 pc_val
= gdbarch_addr_bits_remove (gdbarch
, pc_val
);
253 inferior_registers
.r_pc
^= gdbarch_addr_bits_remove
254 (gdbarch
, inferior_registers
.r_pc
);
255 inferior_registers
.r_pc
|= pc_val
;
261 regcache
->raw_collect (ARM_PS_REGNUM
,
262 (char *) &inferior_registers
.r_cpsr
);
267 regcache
->raw_collect (ARM_PS_REGNUM
, (char *) &psr_val
);
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 (regno
, (char *) &inferior_registers
.r
[regno
]);
281 ret
= ptrace (PT_SETREGS
, regcache
->ptid ().pid (),
282 (PTRACE_TYPE_ARG3
) &inferior_registers
, 0);
285 warning (_("unable to write register %d to inferior"), regno
);
289 store_regs (const struct regcache
*regcache
)
291 struct gdbarch
*gdbarch
= regcache
->arch ();
292 struct reg inferior_registers
;
297 for (regno
= ARM_A1_REGNUM
; regno
< ARM_SP_REGNUM
; regno
++)
298 regcache
->raw_collect (regno
, (char *) &inferior_registers
.r
[regno
]);
300 regcache
->raw_collect (ARM_SP_REGNUM
, (char *) &inferior_registers
.r_sp
);
301 regcache
->raw_collect (ARM_LR_REGNUM
, (char *) &inferior_registers
.r_lr
);
305 regcache
->raw_collect (ARM_PC_REGNUM
, (char *) &inferior_registers
.r_pc
);
306 regcache
->raw_collect (ARM_PS_REGNUM
,
307 (char *) &inferior_registers
.r_cpsr
);
314 regcache
->raw_collect (ARM_PC_REGNUM
, (char *) &pc_val
);
315 regcache
->raw_collect (ARM_PS_REGNUM
, (char *) &psr_val
);
317 pc_val
= gdbarch_addr_bits_remove (gdbarch
, pc_val
);
318 psr_val
^= gdbarch_addr_bits_remove (gdbarch
, psr_val
);
320 inferior_registers
.r_pc
= pc_val
| psr_val
;
323 ret
= ptrace (PT_SETREGS
, regcache
->ptid ().pid (),
324 (PTRACE_TYPE_ARG3
) &inferior_registers
, 0);
327 warning (_("unable to store general registers"));
331 store_fp_register (const struct regcache
*regcache
, int regno
)
333 struct fpreg inferior_fp_registers
;
334 int ret
= ptrace (PT_GETFPREGS
, regcache
->ptid ().pid (),
335 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, 0);
336 struct vfpreg
&vfp
= inferior_fp_registers
.fpr_vfp
;
340 warning (_("unable to fetch floating-point registers"));
344 struct gdbarch_tdep
*tdep
= gdbarch_tdep (regcache
->arch ());
345 if (regno
== ARM_FPSCR_REGNUM
&& tdep
->vfp_register_count
!= 0)
346 regcache
->raw_collect (ARM_FPSCR_REGNUM
, (char *) &vfp
.vfp_fpscr
);
347 else if (regno
>= ARM_D0_REGNUM
348 && regno
<= ARM_D0_REGNUM
+ tdep
->vfp_register_count
)
350 regcache
->raw_collect (regno
,
351 (char *) &vfp
.vfp_regs
[regno
- ARM_D0_REGNUM
]);
354 warning (_("Invalid register number."));
356 ret
= ptrace (PT_SETFPREGS
, regcache
->ptid ().pid (),
357 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, 0);
360 warning (_("unable to write register %d to inferior"), regno
);
364 store_fp_regs (const struct regcache
*regcache
)
366 struct gdbarch_tdep
*tdep
= gdbarch_tdep (regcache
->arch ());
367 if (tdep
->vfp_register_count
== 0)
371 for (int regno
= 0; regno
<= tdep
->vfp_register_count
; regno
++)
372 regcache
->raw_collect
373 (regno
+ ARM_D0_REGNUM
, (char *) &fpregs
.fpr_vfp
.vfp_regs
[regno
]);
375 regcache
->raw_collect (ARM_FPSCR_REGNUM
,
376 (char *) &fpregs
.fpr_vfp
.vfp_fpscr
);
378 int ret
= ptrace (PT_SETFPREGS
, regcache
->ptid ().pid (),
379 (PTRACE_TYPE_ARG3
) &fpregs
, 0);
382 warning (_("unable to store floating-point registers"));
386 arm_netbsd_nat_target::store_registers (struct regcache
*regcache
, int regno
)
390 if (regno
< ARM_F0_REGNUM
|| regno
> ARM_FPS_REGNUM
)
391 store_register (regcache
, regno
);
393 store_fp_register (regcache
, regno
);
397 store_regs (regcache
);
398 store_fp_regs (regcache
);
402 const struct target_desc
*
403 arm_netbsd_nat_target::read_description ()
406 size_t len
= sizeof (flag
);
408 if (sysctlbyname("machdep.fpu_present", &flag
, &len
, NULL
, 0) != 0
410 return arm_read_description (ARM_FP_TYPE_NONE
);
413 if (sysctlbyname("machdep.neon_present", &flag
, &len
, NULL
, 0) == 0 && flag
)
414 return aarch32_read_description ();
416 return arm_read_description (ARM_FP_TYPE_VFPV3
);
420 fetch_elfcore_registers (struct regcache
*regcache
,
421 gdb_byte
*core_reg_sect
, unsigned core_reg_size
,
422 int which
, CORE_ADDR ignore
)
425 struct fpreg fparegset
;
429 case 0: /* Integer registers. */
430 if (core_reg_size
!= sizeof (struct reg
))
431 warning (_("wrong size of register set in core file"));
434 /* The memcpy may be unnecessary, but we can't really be sure
435 of the alignment of the data in the core file. */
436 memcpy (&gregset
, core_reg_sect
, sizeof (gregset
));
437 arm_supply_gregset (regcache
, &gregset
);
442 /* cbiesinger/2020-02-12 -- as far as I can tell, ARM/NetBSD does
443 not write any floating point registers into the core file (tested
444 with NetBSD 9.1_RC1). When it does, this block will need to read them,
445 and the arm-netbsd gdbarch will need a core_read_description function
446 to return the right description for them. */
450 /* Don't know what kind of register request this is; just ignore it. */
455 static struct core_fns arm_netbsd_elfcore_fns
=
457 bfd_target_elf_flavour
, /* core_flavour. */
458 default_check_format
, /* check_format. */
459 default_core_sniffer
, /* core_sniffer. */
460 fetch_elfcore_registers
, /* core_read_registers. */
464 void _initialize_arm_netbsd_nat ();
466 _initialize_arm_netbsd_nat ()
468 add_inf_child_target (&the_arm_netbsd_nat_target
);
470 deprecated_add_core_fns (&arm_netbsd_elfcore_fns
);