]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/ppcobsd-tdep.c
* ppcobsd-tdep.c: Fix typo in comment.
[thirdparty/binutils-gdb.git] / gdb / ppcobsd-tdep.c
CommitLineData
d195bc9f
MK
1/* Target-dependent code for OpenBSD/powerpc.
2
18b2ae85 3 Copyright 2004, 2005 Free Software Foundation, Inc.
d195bc9f
MK
4
5 This file is part of GDB.
6
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.
11
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.
16
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. */
21
22#include "defs.h"
23#include "arch-utils.h"
24#include "osabi.h"
25#include "regcache.h"
26#include "regset.h"
18b2ae85
MK
27#include "trad-frame.h"
28#include "tramp-frame.h"
d195bc9f 29
18b2ae85 30#include "gdb_assert.h"
d195bc9f
MK
31#include "gdb_string.h"
32
33#include "ppc-tdep.h"
34#include "ppcobsd-tdep.h"
35#include "solib-svr4.h"
36
37/* Register offsets from <machine/reg.h>. */
38struct ppc_reg_offsets ppcobsd_reg_offsets;
39\f
40
41/* Core file support. */
42
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. */
46
47void
48ppcobsd_supply_gregset (const struct regset *regset,
49 struct regcache *regcache, int regnum,
50 const void *gregs, size_t len)
51{
383f0f5b
JB
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.
58
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));
63
d195bc9f
MK
64 ppc_supply_gregset (regset, regcache, regnum, gregs, len);
65 ppc_supply_fpregset (regset, regcache, regnum, gregs, len);
66}
67
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
71 REGSET. */
72
73void
74ppcobsd_collect_gregset (const struct regset *regset,
75 const struct regcache *regcache, int regnum,
76 void *gregs, size_t len)
77{
383f0f5b
JB
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.
84
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));
89
d195bc9f
MK
90 ppc_collect_gregset (regset, regcache, regnum, gregs, len);
91 ppc_collect_fpregset (regset, regcache, regnum, gregs, len);
92}
93
5d6210f0 94/* OpenBSD/powerpc register set. */
d195bc9f
MK
95
96struct regset ppcobsd_gregset =
97{
98 &ppcobsd_reg_offsets,
99 ppcobsd_supply_gregset
100};
101
102/* Return the appropriate register set for the core section identified
103 by SECT_NAME and SECT_SIZE. */
104
105static const struct regset *
106ppcobsd_regset_from_core_section (struct gdbarch *gdbarch,
107 const char *sect_name, size_t sect_size)
108{
109 if (strcmp (sect_name, ".reg") == 0 && sect_size >= 412)
110 return &ppcobsd_gregset;
111
112 return NULL;
113}
114\f
115
18b2ae85
MK
116/* Signal trampolines. */
117
118static void
119ppcobsd_sigtramp_cache_init (const struct tramp_frame *self,
120 struct frame_info *next_frame,
121 struct trad_frame_cache *this_cache,
122 CORE_ADDR func)
123{
124 struct gdbarch *gdbarch = get_frame_arch (next_frame);
125 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
126 CORE_ADDR addr, base;
127 int i;
128
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)
132 {
133 int regnum = i + tdep->ppc_gp0_regnum;
134 trad_frame_set_reg_addr (this_cache, regnum, addr);
135 }
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;
146
147 /* Construct the frame ID using the function start. */
148 trad_frame_set_id (this_cache, frame_id_build (base, func));
149}
150
151static const struct tramp_frame ppcobsd_sigtramp =
152{
153 SIGTRAMP_FRAME,
154 4,
155 {
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 }
164 },
165 ppcobsd_sigtramp_cache_init
166};
18b2ae85 167\f
5d6210f0 168
d195bc9f
MK
169static void
170ppcobsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
171{
172 /* OpenBSD uses SVR4-style shared libraries. */
d195bc9f
MK
173 set_solib_svr4_fetch_link_map_offsets
174 (gdbarch, svr4_ilp32_fetch_link_map_offsets);
175
176 set_gdbarch_regset_from_core_section
177 (gdbarch, ppcobsd_regset_from_core_section);
18b2ae85
MK
178
179 tramp_frame_prepend_unwinder (gdbarch, &ppcobsd_sigtramp);
d195bc9f
MK
180}
181\f
182
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
186
187static enum gdb_osabi
188ppcobsd_core_osabi_sniffer (bfd *abfd)
189{
190 if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
191 return GDB_OSABI_NETBSD_CORE;
192
193 return GDB_OSABI_UNKNOWN;
194}
195\f
196
197/* Provide a prototype to silence -Wmissing-prototypes. */
198void _initialize_ppcobsd_tdep (void);
199
200void
201_initialize_ppcobsd_tdep (void)
202{
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);
206
5d6210f0
MK
207 gdbarch_register_osabi (bfd_arch_rs6000, 0, GDB_OSABI_OPENBSD_ELF,
208 ppcobsd_init_abi);
d195bc9f
MK
209 gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_OPENBSD_ELF,
210 ppcobsd_init_abi);
211
212 /* Avoid initializing the register offsets again if they were
213 already initailized by ppcobsd-nat.c. */
214 if (ppcobsd_reg_offsets.pc_offset == 0)
215 {
216 /* General-purpose registers. */
217 ppcobsd_reg_offsets.r0_offset = 0;
218 ppcobsd_reg_offsets.pc_offset = 384;
219 ppcobsd_reg_offsets.ps_offset = 388;
220 ppcobsd_reg_offsets.cr_offset = 392;
221 ppcobsd_reg_offsets.lr_offset = 396;
222 ppcobsd_reg_offsets.ctr_offset = 400;
223 ppcobsd_reg_offsets.xer_offset = 404;
224 ppcobsd_reg_offsets.mq_offset = 408;
225
226 /* Floating-point registers. */
227 ppcobsd_reg_offsets.f0_offset = 128;
228 ppcobsd_reg_offsets.fpscr_offset = -1;
229
230 /* AltiVec registers. */
231 ppcobsd_reg_offsets.vr0_offset = 0;
232 ppcobsd_reg_offsets.vscr_offset = 512;
233 ppcobsd_reg_offsets.vrsave_offset = 520;
234 }
235}