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/>. */
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
;
44 arm_supply_gregset (struct regcache
*regcache
, struct reg
*gregset
)
49 /* Integer registers. */
50 for (regno
= ARM_A1_REGNUM
; regno
< ARM_SP_REGNUM
; regno
++)
51 regcache
->raw_supply (regno
, (char *) &gregset
->r
[regno
]);
53 regcache
->raw_supply (ARM_SP_REGNUM
, (char *) &gregset
->r_sp
);
54 regcache
->raw_supply (ARM_LR_REGNUM
, (char *) &gregset
->r_lr
);
55 /* This is ok: we're running native... */
56 r_pc
= gdbarch_addr_bits_remove (regcache
->arch (), gregset
->r_pc
);
57 regcache
->raw_supply (ARM_PC_REGNUM
, (char *) &r_pc
);
60 regcache
->raw_supply (ARM_PS_REGNUM
, (char *) &gregset
->r_cpsr
);
62 regcache
->raw_supply (ARM_PS_REGNUM
, (char *) &gregset
->r_pc
);
66 arm_supply_fparegset (struct regcache
*regcache
, struct fpreg
*fparegset
)
70 for (regno
= ARM_F0_REGNUM
; regno
<= ARM_F7_REGNUM
; regno
++)
71 regcache
->raw_supply (regno
,
72 (char *) &fparegset
->fpr
[regno
- ARM_F0_REGNUM
]);
74 regcache
->raw_supply (ARM_FPS_REGNUM
, (char *) &fparegset
->fpr_fpsr
);
78 fetch_register (struct regcache
*regcache
, int regno
)
80 struct reg inferior_registers
;
83 ret
= ptrace (PT_GETREGS
, regcache
->ptid ().pid (),
84 (PTRACE_TYPE_ARG3
) &inferior_registers
, 0);
88 warning (_("unable to fetch general register"));
95 regcache
->raw_supply (ARM_SP_REGNUM
, (char *) &inferior_registers
.r_sp
);
99 regcache
->raw_supply (ARM_LR_REGNUM
, (char *) &inferior_registers
.r_lr
);
103 /* This is ok: we're running native... */
104 inferior_registers
.r_pc
= gdbarch_addr_bits_remove
106 inferior_registers
.r_pc
);
107 regcache
->raw_supply (ARM_PC_REGNUM
, (char *) &inferior_registers
.r_pc
);
112 regcache
->raw_supply (ARM_PS_REGNUM
,
113 (char *) &inferior_registers
.r_cpsr
);
115 regcache
->raw_supply (ARM_PS_REGNUM
,
116 (char *) &inferior_registers
.r_pc
);
120 regcache
->raw_supply (regno
, (char *) &inferior_registers
.r
[regno
]);
126 fetch_regs (struct regcache
*regcache
)
128 struct reg inferior_registers
;
132 ret
= ptrace (PT_GETREGS
, regcache
->ptid ().pid (),
133 (PTRACE_TYPE_ARG3
) &inferior_registers
, 0);
137 warning (_("unable to fetch general registers"));
141 arm_supply_gregset (regcache
, &inferior_registers
);
145 fetch_fp_register (struct regcache
*regcache
, int regno
)
147 struct fpreg inferior_fp_registers
;
150 ret
= ptrace (PT_GETFPREGS
, regcache
->ptid ().pid (),
151 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, 0);
155 warning (_("unable to fetch floating-point register"));
162 regcache
->raw_supply (ARM_FPS_REGNUM
,
163 (char *) &inferior_fp_registers
.fpr_fpsr
);
168 (regno
, (char *) &inferior_fp_registers
.fpr
[regno
- ARM_F0_REGNUM
]);
174 fetch_fp_regs (struct regcache
*regcache
)
176 struct fpreg inferior_fp_registers
;
180 ret
= ptrace (PT_GETFPREGS
, regcache
->ptid ().pid (),
181 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, 0);
185 warning (_("unable to fetch general registers"));
189 arm_supply_fparegset (regcache
, &inferior_fp_registers
);
193 arm_nbsd_nat_target::fetch_registers (struct regcache
*regcache
, int regno
)
197 if (regno
< ARM_F0_REGNUM
|| regno
> ARM_FPS_REGNUM
)
198 fetch_register (regcache
, regno
);
200 fetch_fp_register (regcache
, regno
);
204 fetch_regs (regcache
);
205 fetch_fp_regs (regcache
);
211 store_register (const struct regcache
*regcache
, int regno
)
213 struct gdbarch
*gdbarch
= regcache
->arch ();
214 struct reg inferior_registers
;
217 ret
= ptrace (PT_GETREGS
, regcache
->ptid ().pid (),
218 (PTRACE_TYPE_ARG3
) &inferior_registers
, 0);
222 warning (_("unable to fetch general registers"));
229 regcache
->raw_collect (ARM_SP_REGNUM
, (char *) &inferior_registers
.r_sp
);
233 regcache
->raw_collect (ARM_LR_REGNUM
, (char *) &inferior_registers
.r_lr
);
238 regcache
->raw_collect (ARM_PC_REGNUM
,
239 (char *) &inferior_registers
.r_pc
);
244 regcache
->raw_collect (ARM_PC_REGNUM
, (char *) &pc_val
);
246 pc_val
= gdbarch_addr_bits_remove (gdbarch
, pc_val
);
247 inferior_registers
.r_pc
^= gdbarch_addr_bits_remove
248 (gdbarch
, inferior_registers
.r_pc
);
249 inferior_registers
.r_pc
|= pc_val
;
255 regcache
->raw_collect (ARM_PS_REGNUM
,
256 (char *) &inferior_registers
.r_cpsr
);
261 regcache
->raw_collect (ARM_PS_REGNUM
, (char *) &psr_val
);
263 psr_val
^= gdbarch_addr_bits_remove (gdbarch
, psr_val
);
264 inferior_registers
.r_pc
= gdbarch_addr_bits_remove
265 (gdbarch
, inferior_registers
.r_pc
);
266 inferior_registers
.r_pc
|= psr_val
;
271 regcache
->raw_collect (regno
, (char *) &inferior_registers
.r
[regno
]);
275 ret
= ptrace (PT_SETREGS
, regcache
->ptid ().pid (),
276 (PTRACE_TYPE_ARG3
) &inferior_registers
, 0);
279 warning (_("unable to write register %d to inferior"), regno
);
283 store_regs (const struct regcache
*regcache
)
285 struct gdbarch
*gdbarch
= regcache
->arch ();
286 struct reg inferior_registers
;
291 for (regno
= ARM_A1_REGNUM
; regno
< ARM_SP_REGNUM
; regno
++)
292 regcache
->raw_collect (regno
, (char *) &inferior_registers
.r
[regno
]);
294 regcache
->raw_collect (ARM_SP_REGNUM
, (char *) &inferior_registers
.r_sp
);
295 regcache
->raw_collect (ARM_LR_REGNUM
, (char *) &inferior_registers
.r_lr
);
299 regcache
->raw_collect (ARM_PC_REGNUM
, (char *) &inferior_registers
.r_pc
);
300 regcache
->raw_collect (ARM_PS_REGNUM
,
301 (char *) &inferior_registers
.r_cpsr
);
308 regcache
->raw_collect (ARM_PC_REGNUM
, (char *) &pc_val
);
309 regcache
->raw_collect (ARM_PS_REGNUM
, (char *) &psr_val
);
311 pc_val
= gdbarch_addr_bits_remove (gdbarch
, pc_val
);
312 psr_val
^= gdbarch_addr_bits_remove (gdbarch
, psr_val
);
314 inferior_registers
.r_pc
= pc_val
| psr_val
;
317 ret
= ptrace (PT_SETREGS
, regcache
->ptid ().pid (),
318 (PTRACE_TYPE_ARG3
) &inferior_registers
, 0);
321 warning (_("unable to store general registers"));
325 store_fp_register (const struct regcache
*regcache
, int regno
)
327 struct fpreg inferior_fp_registers
;
330 ret
= ptrace (PT_GETFPREGS
, regcache
->ptid ().pid (),
331 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, 0);
335 warning (_("unable to fetch floating-point registers"));
342 regcache
->raw_collect (ARM_FPS_REGNUM
,
343 (char *) &inferior_fp_registers
.fpr_fpsr
);
347 regcache
->raw_collect
348 (regno
, (char *) &inferior_fp_registers
.fpr
[regno
- ARM_F0_REGNUM
]);
352 ret
= ptrace (PT_SETFPREGS
, regcache
->ptid ().pid (),
353 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, 0);
356 warning (_("unable to write register %d to inferior"), regno
);
360 store_fp_regs (const struct regcache
*regcache
)
362 struct fpreg inferior_fp_registers
;
367 for (regno
= ARM_F0_REGNUM
; regno
<= ARM_F7_REGNUM
; regno
++)
368 regcache
->raw_collect
369 (regno
, (char *) &inferior_fp_registers
.fpr
[regno
- ARM_F0_REGNUM
]);
371 regcache
->raw_collect (ARM_FPS_REGNUM
,
372 (char *) &inferior_fp_registers
.fpr_fpsr
);
374 ret
= ptrace (PT_SETFPREGS
, regcache
->ptid ().pid (),
375 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, 0);
378 warning (_("unable to store floating-point registers"));
382 arm_nbsd_nat_target::store_registers (struct regcache
*regcache
, int regno
)
386 if (regno
< ARM_F0_REGNUM
|| regno
> ARM_FPS_REGNUM
)
387 store_register (regcache
, regno
);
389 store_fp_register (regcache
, regno
);
393 store_regs (regcache
);
394 store_fp_regs (regcache
);
399 fetch_elfcore_registers (struct regcache
*regcache
,
400 char *core_reg_sect
, unsigned core_reg_size
,
401 int which
, CORE_ADDR ignore
)
404 struct fpreg fparegset
;
408 case 0: /* Integer registers. */
409 if (core_reg_size
!= sizeof (struct reg
))
410 warning (_("wrong size of register set in core file"));
413 /* The memcpy may be unnecessary, but we can't really be sure
414 of the alignment of the data in the core file. */
415 memcpy (&gregset
, core_reg_sect
, sizeof (gregset
));
416 arm_supply_gregset (regcache
, &gregset
);
421 if (core_reg_size
!= sizeof (struct fpreg
))
422 warning (_("wrong size of FPA register set in core file"));
425 /* The memcpy may be unnecessary, but we can't really be sure
426 of the alignment of the data in the core file. */
427 memcpy (&fparegset
, core_reg_sect
, sizeof (fparegset
));
428 arm_supply_fparegset (regcache
, &fparegset
);
433 /* Don't know what kind of register request this is; just ignore it. */
438 static struct core_fns arm_netbsd_elfcore_fns
=
440 bfd_target_elf_flavour
, /* core_flavour. */
441 default_check_format
, /* check_format. */
442 default_core_sniffer
, /* core_sniffer. */
443 fetch_elfcore_registers
, /* core_read_registers. */
448 _initialize_arm_netbsd_nat (void)
450 add_inf_child_target (&the_arm_netbsd_nat_target
);
452 deprecated_add_core_fns (&arm_netbsd_elfcore_fns
);