1 /* Native-dependent code for BSD Unix running on ARM's, for GDB.
3 Copyright (C) 1988, 1989, 1991, 1992, 1994, 1996, 1999, 2002, 2004
4 Free Software Foundation, Inc.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
29 #include "gdb_string.h"
30 #include <sys/types.h>
31 #include <sys/ptrace.h>
32 #include <machine/reg.h>
33 #include <machine/frame.h>
35 /* Support for debugging kernel virtual memory images. */
36 #include <machine/pcb.h>
39 #include "inf-ptrace.h"
42 #ifndef HAVE_GREGSET_T
43 typedef struct reg gregset_t
;
46 #ifndef HAVE_FPREGSET_T
47 typedef struct fpreg fpregset_t
;
52 extern int arm_apcs_32
;
55 armnbsd_supply_pcb (struct regcache
*regcache
, struct pcb
*pcb
)
57 struct switchframe sf
;
59 /* The following is true for NetBSD/arm32 in 5.0 and after:
61 The pcb contains r8-r13 (sp) at the point of context switch in
62 cpu_switchto() or call of dumpsys(). At that point we have a
63 stack frame as described by `struct switchframe', which for
64 NetBSD/arm32 has the following layout:
73 we reconstruct the register state as it would look when we just
74 returned from cpu_switchto() or dumpsys(). */
79 /* The stack pointer shouldn't be zero. */
80 if (pcb
->pcb_un
.un_32
.pcb32_sp
== 0)
83 read_memory (pcb
->pcb_un
.un_32
.pcb32_sp
, (gdb_byte
*) &sf
, sizeof sf
);
85 regcache_raw_supply (regcache
, ARM_PC_REGNUM
, &sf
.sf_pc
);
86 regcache_raw_supply (regcache
, ARM_SP_REGNUM
, &pcb
->pcb_un
.un_32
.pcb32_sp
);
87 regcache_raw_supply (regcache
, 12, &pcb
->pcb_un
.un_32
.pcb32_r12
);
88 regcache_raw_supply (regcache
, 11, &pcb
->pcb_un
.un_32
.pcb32_r11
);
89 regcache_raw_supply (regcache
, 10, &pcb
->pcb_un
.un_32
.pcb32_r10
);
90 regcache_raw_supply (regcache
, 9, &pcb
->pcb_un
.un_32
.pcb32_r9
);
91 regcache_raw_supply (regcache
, 8, &pcb
->pcb_un
.un_32
.pcb32_r8
);
92 regcache_raw_supply (regcache
, 7, &sf
.sf_r7
);
93 regcache_raw_supply (regcache
, 6, &sf
.sf_r6
);
94 regcache_raw_supply (regcache
, 5, &sf
.sf_r5
);
95 regcache_raw_supply (regcache
, 4, &sf
.sf_r4
);
101 supply_gregset (gregset_t
*gregset
)
106 /* Integer registers. */
107 for (regno
= ARM_A1_REGNUM
; regno
< ARM_SP_REGNUM
; regno
++)
108 regcache_raw_supply (current_regcache
, regno
, (char *) &gregset
->r
[regno
]);
110 regcache_raw_supply (current_regcache
, ARM_SP_REGNUM
,
111 (char *) &gregset
->r_sp
);
112 regcache_raw_supply (current_regcache
, ARM_LR_REGNUM
,
113 (char *) &gregset
->r_lr
);
114 /* This is ok: we're running native... */
115 r_pc
= ADDR_BITS_REMOVE (gregset
->r_pc
);
116 regcache_raw_supply (current_regcache
, ARM_PC_REGNUM
, (char *) &r_pc
);
119 regcache_raw_supply (current_regcache
, ARM_PS_REGNUM
,
120 (char *) &gregset
->r_cpsr
);
122 regcache_raw_supply (current_regcache
, ARM_PS_REGNUM
,
123 (char *) &gregset
->r_pc
);
127 supply_fpregset (fpregset_t
*fpregset
)
131 for (regno
= ARM_F0_REGNUM
; regno
<= ARM_F7_REGNUM
; regno
++)
132 regcache_raw_supply (current_regcache
, regno
,
133 (char *) &fpregset
->fpr
[regno
- ARM_F0_REGNUM
]);
135 regcache_raw_supply (current_regcache
, ARM_FPS_REGNUM
,
136 (char *) &fpregset
->fpr_fpsr
);
140 fill_gregset (gregset_t
*gregsetp
, int regno
)
145 for (regnum
= ARM_A1_REGNUM
; regnum
< ARM_SP_REGNUM
; regnum
++)
146 regcache_raw_collect (current_regcache
, regnum
, (char *) &gregsetp
->r
[regnum
]);
148 else if (regno
>= ARM_A1_REGNUM
&& regno
< ARM_SP_REGNUM
)
149 regcache_raw_collect (current_regcache
, regno
, (char *) &gregsetp
->r
[regno
]);
151 if (ARM_SP_REGNUM
== regno
|| -1 == regno
)
152 regcache_raw_collect (current_regcache
, ARM_SP_REGNUM
, (char *) &gregsetp
->r_sp
);
154 if (ARM_LR_REGNUM
== regno
|| -1 == regno
)
155 regcache_raw_collect (current_regcache
, ARM_LR_REGNUM
, (char *) &gregsetp
->r_lr
);
157 if (ARM_PC_REGNUM
== regno
|| -1 == regno
)
158 regcache_raw_collect (current_regcache
, ARM_PC_REGNUM
, (char *) &gregsetp
->r_pc
);
160 if (ARM_PS_REGNUM
== regno
|| -1 == regno
)
163 regcache_raw_collect (current_regcache
, ARM_PS_REGNUM
, (char *) &gregsetp
->r_cpsr
);
165 regcache_raw_collect (current_regcache
, ARM_PS_REGNUM
, (char *) &gregsetp
->r_pc
);
170 fill_fpregset (fpregset_t
*fpregsetp
, int regno
)
175 for (regnum
= ARM_F0_REGNUM
; regnum
<= ARM_F7_REGNUM
; regnum
++)
176 regcache_raw_collect(current_regcache
, regnum
, (char *) &fpregsetp
->fpr
[regnum
- ARM_F0_REGNUM
]);
178 else if (regno
>= ARM_F0_REGNUM
&& regno
<= ARM_F7_REGNUM
)
179 regcache_raw_collect(current_regcache
, regno
, (char *) &fpregsetp
->fpr
[regno
- ARM_F0_REGNUM
]);
181 if (ARM_FPS_REGNUM
== regno
|| -1 == regno
)
182 regcache_raw_collect (current_regcache
, ARM_FPS_REGNUM
, (char *) &fpregsetp
->fpr_fpsr
);
187 fetch_register (int regno
)
189 struct reg inferior_registers
;
192 ret
= ptrace (PT_GETREGS
, PIDGET (inferior_ptid
),
193 (PTRACE_TYPE_ARG3
) &inferior_registers
, 0);
197 warning (_("unable to fetch general register"));
204 regcache_raw_supply (current_regcache
, ARM_SP_REGNUM
,
205 (char *) &inferior_registers
.r_sp
);
209 regcache_raw_supply (current_regcache
, ARM_LR_REGNUM
,
210 (char *) &inferior_registers
.r_lr
);
214 /* This is ok: we're running native... */
215 inferior_registers
.r_pc
= ADDR_BITS_REMOVE (inferior_registers
.r_pc
);
216 regcache_raw_supply (current_regcache
, ARM_PC_REGNUM
,
217 (char *) &inferior_registers
.r_pc
);
222 regcache_raw_supply (current_regcache
, ARM_PS_REGNUM
,
223 (char *) &inferior_registers
.r_cpsr
);
225 regcache_raw_supply (current_regcache
, ARM_PS_REGNUM
,
226 (char *) &inferior_registers
.r_pc
);
230 regcache_raw_supply (current_regcache
, regno
,
231 (char *) &inferior_registers
.r
[regno
]);
239 struct reg inferior_registers
;
243 ret
= ptrace (PT_GETREGS
, PIDGET (inferior_ptid
),
244 (PTRACE_TYPE_ARG3
) &inferior_registers
, TIDGET (inferior_ptid
));
248 warning (_("unable to fetch general registers"));
252 supply_gregset (&inferior_registers
);
256 fetch_fp_register (int regno
)
258 struct fpreg inferior_fp_registers
;
261 ret
= ptrace (PT_GETFPREGS
, PIDGET (inferior_ptid
),
262 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, TIDGET (inferior_ptid
));
266 warning (_("unable to fetch floating-point register"));
273 regcache_raw_supply (current_regcache
, ARM_FPS_REGNUM
,
274 (char *) &inferior_fp_registers
.fpr_fpsr
);
278 regcache_raw_supply (current_regcache
, regno
,
279 (char *) &inferior_fp_registers
.fpr
[regno
- ARM_F0_REGNUM
]);
287 struct fpreg inferior_fp_registers
;
291 ret
= ptrace (PT_GETFPREGS
, PIDGET (inferior_ptid
),
292 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, TIDGET (inferior_ptid
));
296 warning (_("unable to fetch general registers"));
300 supply_fpregset (&inferior_fp_registers
);
304 armnbsd_fetch_registers (int regno
)
308 if (regno
< ARM_F0_REGNUM
|| regno
> ARM_FPS_REGNUM
)
309 fetch_register (regno
);
311 fetch_fp_register (regno
);
322 store_register (int regno
)
324 struct reg inferior_registers
;
327 ret
= ptrace (PT_GETREGS
, PIDGET (inferior_ptid
),
328 (PTRACE_TYPE_ARG3
) &inferior_registers
, TIDGET (inferior_ptid
));
332 warning (_("unable to fetch general registers"));
339 regcache_raw_collect (current_regcache
, ARM_SP_REGNUM
,
340 (char *) &inferior_registers
.r_sp
);
344 regcache_raw_collect (current_regcache
, ARM_LR_REGNUM
,
345 (char *) &inferior_registers
.r_lr
);
350 regcache_raw_collect (current_regcache
, ARM_PC_REGNUM
,
351 (char *) &inferior_registers
.r_pc
);
356 regcache_raw_collect (current_regcache
, ARM_PC_REGNUM
,
359 pc_val
= ADDR_BITS_REMOVE (pc_val
);
360 inferior_registers
.r_pc
361 ^= ADDR_BITS_REMOVE (inferior_registers
.r_pc
);
362 inferior_registers
.r_pc
|= pc_val
;
368 regcache_raw_collect (current_regcache
, ARM_PS_REGNUM
,
369 (char *) &inferior_registers
.r_cpsr
);
374 regcache_raw_collect (current_regcache
, ARM_PS_REGNUM
,
377 psr_val
^= ADDR_BITS_REMOVE (psr_val
);
378 inferior_registers
.r_pc
= ADDR_BITS_REMOVE (inferior_registers
.r_pc
);
379 inferior_registers
.r_pc
|= psr_val
;
384 regcache_raw_collect (current_regcache
, regno
,
385 (char *) &inferior_registers
.r
[regno
]);
389 ret
= ptrace (PT_SETREGS
, PIDGET (inferior_ptid
),
390 (PTRACE_TYPE_ARG3
) &inferior_registers
, TIDGET (inferior_ptid
));
393 warning (_("unable to write register %d to inferior"), regno
);
399 struct reg inferior_registers
;
404 for (regno
= ARM_A1_REGNUM
; regno
< ARM_SP_REGNUM
; regno
++)
405 regcache_raw_collect (current_regcache
, regno
,
406 (char *) &inferior_registers
.r
[regno
]);
408 regcache_raw_collect (current_regcache
, ARM_SP_REGNUM
,
409 (char *) &inferior_registers
.r_sp
);
410 regcache_raw_collect (current_regcache
, ARM_LR_REGNUM
,
411 (char *) &inferior_registers
.r_lr
);
415 regcache_raw_collect (current_regcache
, ARM_PC_REGNUM
,
416 (char *) &inferior_registers
.r_pc
);
417 regcache_raw_collect (current_regcache
, ARM_PS_REGNUM
,
418 (char *) &inferior_registers
.r_cpsr
);
425 regcache_raw_collect (current_regcache
, ARM_PC_REGNUM
,
427 regcache_raw_collect (current_regcache
, ARM_PS_REGNUM
,
430 pc_val
= ADDR_BITS_REMOVE (pc_val
);
431 psr_val
^= ADDR_BITS_REMOVE (psr_val
);
433 inferior_registers
.r_pc
= pc_val
| psr_val
;
436 ret
= ptrace (PT_SETREGS
, PIDGET (inferior_ptid
),
437 (PTRACE_TYPE_ARG3
) &inferior_registers
, TIDGET (inferior_ptid
));
440 warning (_("unable to store general registers"));
444 store_fp_register (int regno
)
446 struct fpreg inferior_fp_registers
;
449 ret
= ptrace (PT_GETFPREGS
, PIDGET (inferior_ptid
),
450 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, TIDGET (inferior_ptid
));
454 warning (_("unable to fetch floating-point registers"));
461 regcache_raw_collect (current_regcache
, ARM_FPS_REGNUM
,
462 (char *) &inferior_fp_registers
.fpr_fpsr
);
466 regcache_raw_collect (current_regcache
, regno
,
467 (char *) &inferior_fp_registers
.fpr
[regno
- ARM_F0_REGNUM
]);
471 ret
= ptrace (PT_SETFPREGS
, PIDGET (inferior_ptid
),
472 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, TIDGET (inferior_ptid
));
475 warning (_("unable to write register %d to inferior"), regno
);
481 struct fpreg inferior_fp_registers
;
486 for (regno
= ARM_F0_REGNUM
; regno
<= ARM_F7_REGNUM
; regno
++)
487 regcache_raw_collect (current_regcache
, regno
,
488 (char *) &inferior_fp_registers
.fpr
[regno
- ARM_F0_REGNUM
]);
490 regcache_raw_collect (current_regcache
, ARM_FPS_REGNUM
,
491 (char *) &inferior_fp_registers
.fpr_fpsr
);
493 ret
= ptrace (PT_SETFPREGS
, PIDGET (inferior_ptid
),
494 (PTRACE_TYPE_ARG3
) &inferior_fp_registers
, TIDGET (inferior_ptid
));
497 warning (_("unable to store floating-point registers"));
501 armnbsd_store_registers (int regno
)
505 if (regno
< ARM_F0_REGNUM
|| regno
> ARM_FPS_REGNUM
)
506 store_register (regno
);
508 store_fp_register (regno
);
524 fetch_core_registers (char *core_reg_sect
, unsigned core_reg_size
,
525 int which
, CORE_ADDR ignore
)
527 struct md_core
*core_reg
= (struct md_core
*) core_reg_sect
;
531 supply_gregset (&core_reg
->intreg
);
532 supply_fpregset (&core_reg
->freg
);
536 fetch_elfcore_registers (char *core_reg_sect
, unsigned core_reg_size
,
537 int which
, CORE_ADDR ignore
)
540 struct fpreg fpregset
;
544 case 0: /* Integer registers. */
545 if (core_reg_size
!= sizeof (struct reg
))
546 warning (_("wrong size of register set in core file"));
549 /* The memcpy may be unnecessary, but we can't really be sure
550 of the alignment of the data in the core file. */
551 memcpy (&gregset
, core_reg_sect
, sizeof (gregset
));
552 supply_gregset (&gregset
);
557 if (core_reg_size
!= sizeof (struct fpreg
))
558 warning (_("wrong size of FPA register set in core file"));
561 /* The memcpy may be unnecessary, but we can't really be sure
562 of the alignment of the data in the core file. */
563 memcpy (&fpregset
, core_reg_sect
, sizeof (fpregset
));
564 supply_fpregset (&fpregset
);
569 /* Don't know what kind of register request this is; just ignore it. */
574 static struct core_fns arm_netbsd_core_fns
=
576 bfd_target_unknown_flavour
, /* core_flovour. */
577 default_check_format
, /* check_format. */
578 default_core_sniffer
, /* core_sniffer. */
579 fetch_core_registers
, /* core_read_registers. */
583 static struct core_fns arm_netbsd_elfcore_fns
=
585 bfd_target_elf_flavour
, /* core_flovour. */
586 default_check_format
, /* check_format. */
587 default_core_sniffer
, /* core_sniffer. */
588 fetch_elfcore_registers
, /* core_read_registers. */
593 _initialize_arm_netbsd_nat (void)
595 struct target_ops
*t
;
597 t
= inf_ptrace_target ();
598 t
->to_fetch_registers
= armnbsd_fetch_registers
;
599 t
->to_store_registers
= armnbsd_store_registers
;
602 /* Support debugging kernel virtual memory images. */
603 bsd_kvm_add_target (armnbsd_supply_pcb
);
605 deprecated_add_core_fns (&arm_netbsd_core_fns
);
606 deprecated_add_core_fns (&arm_netbsd_elfcore_fns
);