1 /* Target-dependent code for PowerPC systems running NetBSD.
2 Copyright 2002, 2003 Free Software Foundation, Inc.
3 Contributed by Wasabi Systems, 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 2 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, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
26 #include "breakpoint.h"
31 #include "ppcnbsd-tdep.h"
32 #include "nbsd-tdep.h"
34 #include "solib-svr4.h"
36 #define REG_FIXREG_OFFSET(x) ((x) * 4)
37 #define REG_LR_OFFSET (32 * 4)
38 #define REG_CR_OFFSET (33 * 4)
39 #define REG_XER_OFFSET (34 * 4)
40 #define REG_CTR_OFFSET (35 * 4)
41 #define REG_PC_OFFSET (36 * 4)
42 #define SIZEOF_STRUCT_REG (37 * 4)
44 #define FPREG_FPR_OFFSET(x) ((x) * 8)
45 #define FPREG_FPSCR_OFFSET (32 * 8)
46 #define SIZEOF_STRUCT_FPREG (33 * 8)
49 ppcnbsd_supply_reg (char *regs, int regno)
51 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
54 for (i = 0; i <= 31; i++)
56 if (regno == i || regno == -1)
57 supply_register (i, regs + REG_FIXREG_OFFSET (i));
60 if (regno == tdep->ppc_lr_regnum || regno == -1)
61 supply_register (tdep->ppc_lr_regnum, regs + REG_LR_OFFSET);
63 if (regno == tdep->ppc_cr_regnum || regno == -1)
64 supply_register (tdep->ppc_cr_regnum, regs + REG_CR_OFFSET);
66 if (regno == tdep->ppc_xer_regnum || regno == -1)
67 supply_register (tdep->ppc_xer_regnum, regs + REG_XER_OFFSET);
69 if (regno == tdep->ppc_ctr_regnum || regno == -1)
70 supply_register (tdep->ppc_ctr_regnum, regs + REG_CTR_OFFSET);
72 if (regno == PC_REGNUM || regno == -1)
73 supply_register (PC_REGNUM, regs + REG_PC_OFFSET);
77 ppcnbsd_fill_reg (char *regs, int regno)
79 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
82 for (i = 0; i <= 31; i++)
84 if (regno == i || regno == -1)
85 regcache_collect (i, regs + REG_FIXREG_OFFSET (i));
88 if (regno == tdep->ppc_lr_regnum || regno == -1)
89 regcache_collect (tdep->ppc_lr_regnum, regs + REG_LR_OFFSET);
91 if (regno == tdep->ppc_cr_regnum || regno == -1)
92 regcache_collect (tdep->ppc_cr_regnum, regs + REG_CR_OFFSET);
94 if (regno == tdep->ppc_xer_regnum || regno == -1)
95 regcache_collect (tdep->ppc_xer_regnum, regs + REG_XER_OFFSET);
97 if (regno == tdep->ppc_ctr_regnum || regno == -1)
98 regcache_collect (tdep->ppc_ctr_regnum, regs + REG_CTR_OFFSET);
100 if (regno == PC_REGNUM || regno == -1)
101 regcache_collect (PC_REGNUM, regs + REG_PC_OFFSET);
105 ppcnbsd_supply_fpreg (char *fpregs, int regno)
107 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
110 for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++)
112 if (regno == i || regno == -1)
113 supply_register (i, fpregs + FPREG_FPR_OFFSET (i - FP0_REGNUM));
116 if (regno == tdep->ppc_fpscr_regnum || regno == -1)
117 supply_register (tdep->ppc_fpscr_regnum, fpregs + FPREG_FPSCR_OFFSET);
121 ppcnbsd_fill_fpreg (char *fpregs, int regno)
123 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
126 for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++)
128 if (regno == i || regno == -1)
129 regcache_collect (i, fpregs + FPREG_FPR_OFFSET (i - FP0_REGNUM));
132 if (regno == tdep->ppc_fpscr_regnum || regno == -1)
133 regcache_collect (tdep->ppc_fpscr_regnum, fpregs + FPREG_FPSCR_OFFSET);
137 fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
142 /* We get everything from one section. */
146 regs = core_reg_sect;
147 fpregs = core_reg_sect + SIZEOF_STRUCT_REG;
149 /* Integer registers. */
150 ppcnbsd_supply_reg (regs, -1);
152 /* Floating point registers. */
153 ppcnbsd_supply_fpreg (fpregs, -1);
157 fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size, int which,
162 case 0: /* Integer registers. */
163 if (core_reg_size != SIZEOF_STRUCT_REG)
164 warning ("Wrong size register set in core file.");
166 ppcnbsd_supply_reg (core_reg_sect, -1);
169 case 2: /* Floating point registers. */
170 if (core_reg_size != SIZEOF_STRUCT_FPREG)
171 warning ("Wrong size FP register set in core file.");
173 ppcnbsd_supply_fpreg (core_reg_sect, -1);
177 /* Don't know what kind of register request this is; just ignore it. */
182 static struct core_fns ppcnbsd_core_fns =
184 bfd_target_unknown_flavour, /* core_flavour */
185 default_check_format, /* check_format */
186 default_core_sniffer, /* core_sniffer */
187 fetch_core_registers, /* core_read_registers */
191 static struct core_fns ppcnbsd_elfcore_fns =
193 bfd_target_elf_flavour, /* core_flavour */
194 default_check_format, /* check_format */
195 default_core_sniffer, /* core_sniffer */
196 fetch_elfcore_registers, /* core_read_registers */
201 ppcnbsd_pc_in_sigtramp (CORE_ADDR pc, char *func_name)
203 /* FIXME: Need to add support for kernel-provided signal trampolines. */
204 return (nbsd_pc_in_sigtramp (pc, func_name));
207 /* NetBSD is confused. It appears that 1.5 was using the correct SVr4
208 convention but, 1.6 switched to the below broken convention. For
209 the moment use the broken convention. Ulgh!. */
212 ppcnbsd_use_struct_convention (int gcc_p, struct type *value_type)
214 if ((TYPE_LENGTH (value_type) == 16 || TYPE_LENGTH (value_type) == 8)
215 && TYPE_VECTOR (value_type))
218 return !(TYPE_LENGTH (value_type) == 1
219 || TYPE_LENGTH (value_type) == 2
220 || TYPE_LENGTH (value_type) == 4
221 || TYPE_LENGTH (value_type) == 8);
225 ppcnbsd_init_abi (struct gdbarch_info info,
226 struct gdbarch *gdbarch)
228 set_gdbarch_pc_in_sigtramp (gdbarch, ppcnbsd_pc_in_sigtramp);
229 /* For NetBSD, this is an on again, off again thing. Some systems
230 do use the broken struct convention, and some don't. */
231 set_gdbarch_use_struct_convention (gdbarch, ppcnbsd_use_struct_convention);
232 set_gdbarch_extract_return_value (gdbarch, ppc_sysv_abi_broken_extract_return_value);
233 set_gdbarch_store_return_value (gdbarch, ppc_sysv_abi_broken_store_return_value);
234 set_solib_svr4_fetch_link_map_offsets (gdbarch,
235 nbsd_ilp32_solib_svr4_fetch_link_map_offsets);
239 _initialize_ppcnbsd_tdep (void)
241 gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_NETBSD_ELF,
244 add_core_fns (&ppcnbsd_core_fns);
245 add_core_fns (&ppcnbsd_elfcore_fns);