1 /* Target-dependent code for OpenBSD/powerpc.
3 Copyright 2004, 2005 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 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. */
23 #include "arch-utils.h"
27 #include "trad-frame.h"
28 #include "tramp-frame.h"
30 #include "gdb_assert.h"
31 #include "gdb_string.h"
34 #include "ppcobsd-tdep.h"
35 #include "solib-svr4.h"
37 /* Register offsets from <machine/reg.h>. */
38 struct ppc_reg_offsets ppcobsd_reg_offsets;
41 /* Core file support. */
43 /* Supply register REGNUM in the general-purpose register set REGSET
44 from the buffer specified by GREGS and LEN to register cache
45 REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
48 ppcobsd_supply_gregset (const struct regset *regset,
49 struct regcache *regcache, int regnum,
50 const void *gregs, size_t len)
52 /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
53 point registers. Traditionally, GDB's register set has still
54 listed the floating point registers for such machines, so this
55 code is harmless. However, the new E500 port actually omits the
56 floating point registers entirely from the register set --- they
57 don't even have register numbers assigned to them.
59 It's not clear to me how best to update this code, so this assert
60 will alert the first person to encounter the OpenBSD/E500
61 combination to the problem. */
62 gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
64 ppc_supply_gregset (regset, regcache, regnum, gregs, len);
65 ppc_supply_fpregset (regset, regcache, regnum, gregs, len);
68 /* Collect register REGNUM in the general-purpose register set
69 REGSET. from register cache REGCACHE into the buffer specified by
70 GREGS and LEN. If REGNUM is -1, do this for all registers in
74 ppcobsd_collect_gregset (const struct regset *regset,
75 const struct regcache *regcache, int regnum,
76 void *gregs, size_t len)
78 /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
79 point registers. Traditionally, GDB's register set has still
80 listed the floating point registers for such machines, so this
81 code is harmless. However, the new E500 port actually omits the
82 floating point registers entirely from the register set --- they
83 don't even have register numbers assigned to them.
85 It's not clear to me how best to update this code, so this assert
86 will alert the first person to encounter the OpenBSD/E500
87 combination to the problem. */
88 gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
90 ppc_collect_gregset (regset, regcache, regnum, gregs, len);
91 ppc_collect_fpregset (regset, regcache, regnum, gregs, len);
94 /* OpenBS/powerpc register set. */
96 struct regset ppcobsd_gregset =
99 ppcobsd_supply_gregset
102 /* Return the appropriate register set for the core section identified
103 by SECT_NAME and SECT_SIZE. */
105 static const struct regset *
106 ppcobsd_regset_from_core_section (struct gdbarch *gdbarch,
107 const char *sect_name, size_t sect_size)
109 if (strcmp (sect_name, ".reg") == 0 && sect_size >= 412)
110 return &ppcobsd_gregset;
116 /* Signal trampolines. */
119 ppcobsd_sigtramp_cache_init (const struct tramp_frame *self,
120 struct frame_info *next_frame,
121 struct trad_frame_cache *this_cache,
124 struct gdbarch *gdbarch = get_frame_arch (next_frame);
125 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
126 CORE_ADDR addr, base;
129 base = frame_unwind_register_unsigned (next_frame, SP_REGNUM);
130 addr = base + 0x18 + 2 * tdep->wordsize;
131 for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize)
133 int regnum = i + tdep->ppc_gp0_regnum;
134 trad_frame_set_reg_addr (this_cache, regnum, addr);
136 trad_frame_set_reg_addr (this_cache, tdep->ppc_lr_regnum, addr);
137 addr += tdep->wordsize;
138 trad_frame_set_reg_addr (this_cache, tdep->ppc_cr_regnum, addr);
139 addr += tdep->wordsize;
140 trad_frame_set_reg_addr (this_cache, tdep->ppc_xer_regnum, addr);
141 addr += tdep->wordsize;
142 trad_frame_set_reg_addr (this_cache, tdep->ppc_ctr_regnum, addr);
143 addr += tdep->wordsize;
144 trad_frame_set_reg_addr (this_cache, PC_REGNUM, addr); /* SRR0? */
145 addr += tdep->wordsize;
147 /* Construct the frame ID using the function start. */
148 trad_frame_set_id (this_cache, frame_id_build (base, func));
151 static const struct tramp_frame ppcobsd_sigtramp =
156 { 0x3821fff0, -1 }, /* add r1,r1,-16 */
157 { 0x4e800021, -1 }, /* blrl */
158 { 0x38610018, -1 }, /* addi r3,r1,24 */
159 { 0x38000067, -1 }, /* li r0,103 */
160 { 0x44000002, -1 }, /* sc */
161 { 0x38000001, -1 }, /* li r0,1 */
162 { 0x44000002, -1 }, /* sc */
163 { TRAMP_SENTINEL_INSN, -1 }
165 ppcobsd_sigtramp_cache_init
170 ppcobsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
172 /* OpenBSD uses SVR4-style shared libraries. */
173 set_solib_svr4_fetch_link_map_offsets
174 (gdbarch, svr4_ilp32_fetch_link_map_offsets);
176 set_gdbarch_regset_from_core_section
177 (gdbarch, ppcobsd_regset_from_core_section);
179 tramp_frame_prepend_unwinder (gdbarch, &ppcobsd_sigtramp);
183 /* OpenBSD uses uses the traditional NetBSD core file format, even for
184 ports that use ELF. */
185 #define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF
187 static enum gdb_osabi
188 ppcobsd_core_osabi_sniffer (bfd *abfd)
190 if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
191 return GDB_OSABI_NETBSD_CORE;
193 return GDB_OSABI_UNKNOWN;
197 /* Provide a prototype to silence -Wmissing-prototypes. */
198 void _initialize_ppcobsd_tdep (void);
201 _initialize_ppcobsd_tdep (void)
203 /* BFD doesn't set a flavour for NetBSD style a.out core files. */
204 gdbarch_register_osabi_sniffer (bfd_arch_powerpc, bfd_target_unknown_flavour,
205 ppcobsd_core_osabi_sniffer);
207 gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_OPENBSD_ELF,
210 /* Avoid initializing the register offsets again if they were
211 already initailized by ppcobsd-nat.c. */
212 if (ppcobsd_reg_offsets.pc_offset == 0)
214 /* General-purpose registers. */
215 ppcobsd_reg_offsets.r0_offset = 0;
216 ppcobsd_reg_offsets.pc_offset = 384;
217 ppcobsd_reg_offsets.ps_offset = 388;
218 ppcobsd_reg_offsets.cr_offset = 392;
219 ppcobsd_reg_offsets.lr_offset = 396;
220 ppcobsd_reg_offsets.ctr_offset = 400;
221 ppcobsd_reg_offsets.xer_offset = 404;
222 ppcobsd_reg_offsets.mq_offset = 408;
224 /* Floating-point registers. */
225 ppcobsd_reg_offsets.f0_offset = 128;
226 ppcobsd_reg_offsets.fpscr_offset = -1;
228 /* AltiVec registers. */
229 ppcobsd_reg_offsets.vr0_offset = 0;
230 ppcobsd_reg_offsets.vscr_offset = 512;
231 ppcobsd_reg_offsets.vrsave_offset = 520;