Switch the license of all .c files to GPLv3.
[deliverable/binutils-gdb.git] / gdb / sparc64fbsd-tdep.c
CommitLineData
8b39fe56
MK
1/* Target-dependent code for FreeBSD/sparc64.
2
6aba47ca 3 Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
8b39fe56
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
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
8b39fe56
MK
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
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
8b39fe56
MK
19
20#include "defs.h"
386c036b
MK
21#include "frame.h"
22#include "frame-unwind.h"
8b39fe56
MK
23#include "gdbcore.h"
24#include "osabi.h"
25#include "regcache.h"
762c360d 26#include "regset.h"
8b39fe56 27#include "target.h"
386c036b 28#include "trad-frame.h"
8b39fe56 29
386c036b 30#include "gdb_assert.h"
8b39fe56
MK
31#include "gdb_string.h"
32
33#include "sparc64-tdep.h"
9e07977b 34#include "solib-svr4.h"
8b39fe56
MK
35
36/* From <machine/reg.h>. */
386c036b 37const struct sparc_gregset sparc64fbsd_gregset =
8b39fe56 38{
386c036b
MK
39 26 * 8, /* "tstate" */
40 25 * 8, /* %pc */
41 24 * 8, /* %npc */
42 28 * 8, /* %y */
43 16 * 8, /* %fprs */
44 -1,
45 1 * 8, /* %g1 */
46 -1, /* %l0 */
47 8 /* sizeof (%y) */
48};
8b39fe56
MK
49\f
50
51static void
762c360d
MK
52sparc64fbsd_supply_gregset (const struct regset *regset,
53 struct regcache *regcache,
54 int regnum, const void *gregs, size_t len)
8b39fe56 55{
9ea75c57 56 sparc64_supply_gregset (&sparc64fbsd_gregset, regcache, regnum, gregs);
8b39fe56
MK
57}
58
ae036357
MK
59static void
60sparc64fbsd_collect_gregset (const struct regset *regset,
61 const struct regcache *regcache,
62 int regnum, void *gregs, size_t len)
63{
64 sparc64_collect_gregset (&sparc64fbsd_gregset, regcache, regnum, gregs);
65}
66
762c360d
MK
67static void
68sparc64fbsd_supply_fpregset (const struct regset *regset,
69 struct regcache *regcache,
70 int regnum, const void *fpregs, size_t len)
8b39fe56 71{
762c360d
MK
72 sparc64_supply_fpregset (regcache, regnum, fpregs);
73}
ae036357
MK
74
75static void
76sparc64fbsd_collect_fpregset (const struct regset *regset,
77 const struct regcache *regcache,
78 int regnum, void *fpregs, size_t len)
79{
80 sparc64_collect_fpregset (regcache, regnum, fpregs);
81}
8b39fe56
MK
82\f
83
386c036b
MK
84/* Signal trampolines. */
85
86static int
87sparc64fbsd_pc_in_sigtramp (CORE_ADDR pc, char *name)
88{
89 return (name && strcmp (name, "__sigtramp") == 0);
90}
91
92static struct sparc_frame_cache *
93sparc64fbsd_sigtramp_frame_cache (struct frame_info *next_frame,
94 void **this_cache)
95{
96 struct sparc_frame_cache *cache;
97 CORE_ADDR addr, mcontext_addr, sp;
98 LONGEST fprs;
99 int regnum;
100
101 if (*this_cache)
102 return *this_cache;
103
104 cache = sparc_frame_cache (next_frame, this_cache);
105 gdb_assert (cache == *this_cache);
106
107 cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
108
109 /* The third argument is a pointer to an instance of `ucontext_t',
110 which has a member `uc_mcontext' that contains the saved
111 registers. */
112 addr = frame_unwind_register_unsigned (next_frame, SPARC_O2_REGNUM);
113 mcontext_addr = addr + 64;
114
115 /* The following registers travel in the `mc_local' slots of
116 `mcontext_t'. */
117 addr = mcontext_addr + 16 * 8;
118 cache->saved_regs[SPARC64_FPRS_REGNUM].addr = addr + 0 * 8;
119 cache->saved_regs[SPARC64_FSR_REGNUM].addr = addr + 1 * 8;
120
121 /* The following registers travel in the `mc_in' slots of
122 `mcontext_t'. */
123 addr = mcontext_addr + 24 * 8;
124 cache->saved_regs[SPARC64_NPC_REGNUM].addr = addr + 0 * 8;
125 cache->saved_regs[SPARC64_PC_REGNUM].addr = addr + 1 * 8;
126 cache->saved_regs[SPARC64_STATE_REGNUM].addr = addr + 2 * 8;
127 cache->saved_regs[SPARC64_Y_REGNUM].addr = addr + 4 * 8;
128
129 /* The `global' and `out' registers travel in the `mc_global' and
130 `mc_out' slots of `mcontext_t', except for %g0. Since %g0 is
131 always zero, keep the identity encoding. */
132 for (regnum = SPARC_G1_REGNUM, addr = mcontext_addr + 8;
133 regnum <= SPARC_O7_REGNUM; regnum++, addr += 8)
134 cache->saved_regs[regnum].addr = addr;
135
136 /* The `local' and `in' registers have been saved in the register
137 save area. */
138 addr = cache->saved_regs[SPARC_SP_REGNUM].addr;
139 sp = get_frame_memory_unsigned (next_frame, addr, 8);
140 for (regnum = SPARC_L0_REGNUM, addr = sp + BIAS;
141 regnum <= SPARC_I7_REGNUM; regnum++, addr += 8)
142 cache->saved_regs[regnum].addr = addr;
143
144 /* The floating-point registers are only saved if the FEF bit in
145 %fprs has been set. */
146
147#define FPRS_FEF (1 << 2)
148
149 addr = cache->saved_regs[SPARC64_FPRS_REGNUM].addr;
150 fprs = get_frame_memory_unsigned (next_frame, addr, 8);
151 if (fprs & FPRS_FEF)
152 {
153 for (regnum = SPARC_F0_REGNUM, addr = mcontext_addr + 32 * 8;
154 regnum <= SPARC_F31_REGNUM; regnum++, addr += 4)
155 cache->saved_regs[regnum].addr = addr;
156
157 for (regnum = SPARC64_F32_REGNUM;
158 regnum <= SPARC64_F62_REGNUM; regnum++, addr += 8)
159 cache->saved_regs[regnum].addr = addr;
160 }
161
162 return cache;
163}
164
165static void
166sparc64fbsd_sigtramp_frame_this_id (struct frame_info *next_frame,
167 void **this_cache,
168 struct frame_id *this_id)
169{
170 struct sparc_frame_cache *cache =
171 sparc64fbsd_sigtramp_frame_cache (next_frame, this_cache);
172
173 (*this_id) = frame_id_build (cache->base, cache->pc);
174}
175
176static void
177sparc64fbsd_sigtramp_frame_prev_register (struct frame_info *next_frame,
178 void **this_cache,
179 int regnum, int *optimizedp,
180 enum lval_type *lvalp,
181 CORE_ADDR *addrp,
47ef841b 182 int *realnump, gdb_byte *valuep)
386c036b
MK
183{
184 struct sparc_frame_cache *cache =
185 sparc64fbsd_sigtramp_frame_cache (next_frame, this_cache);
186
1f67027d
AC
187 trad_frame_get_prev_register (next_frame, cache->saved_regs, regnum,
188 optimizedp, lvalp, addrp, realnump, valuep);
386c036b
MK
189}
190
191static const struct frame_unwind sparc64fbsd_sigtramp_frame_unwind =
192{
193 SIGTRAMP_FRAME,
194 sparc64fbsd_sigtramp_frame_this_id,
195 sparc64fbsd_sigtramp_frame_prev_register
196};
197
198static const struct frame_unwind *
199sparc64fbsd_sigtramp_frame_sniffer (struct frame_info *next_frame)
200{
201 CORE_ADDR pc = frame_pc_unwind (next_frame);
202 char *name;
203
204 find_pc_partial_function (pc, &name, NULL, NULL);
205 if (sparc64fbsd_pc_in_sigtramp (pc, name))
206 return &sparc64fbsd_sigtramp_frame_unwind;
207
208 return NULL;
209}
210\f
211
8b39fe56
MK
212static void
213sparc64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
214{
762c360d
MK
215 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
216
ae036357
MK
217 tdep->gregset = regset_alloc (gdbarch, sparc64fbsd_supply_gregset,
218 sparc64fbsd_collect_gregset);
762c360d
MK
219 tdep->sizeof_gregset = 256;
220
ae036357
MK
221 tdep->fpregset = regset_alloc (gdbarch, sparc64fbsd_supply_fpregset,
222 sparc64fbsd_collect_fpregset);
762c360d
MK
223 tdep->sizeof_fpregset = 272;
224
386c036b
MK
225 frame_unwind_append_sniffer (gdbarch, sparc64fbsd_sigtramp_frame_sniffer);
226
227 sparc64_init_abi (info, gdbarch);
9e07977b
MK
228
229 /* FreeBSD/sparc64 has SVR4-style shared libraries. */
230 set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
231 set_solib_svr4_fetch_link_map_offsets
232 (gdbarch, svr4_lp64_fetch_link_map_offsets);
8b39fe56
MK
233}
234
235/* Provide a prototype to silence -Wmissing-prototypes. */
236void _initialize_sparc64fbsd_tdep (void);
237
238void
239_initialize_sparc64fbsd_tdep (void)
240{
241 gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
242 GDB_OSABI_FREEBSD_ELF, sparc64fbsd_init_abi);
8b39fe56 243}
This page took 0.361374 seconds and 4 git commands to generate.