SPARC: Replace regset_alloc() invocations by static regset structures.
[deliverable/binutils-gdb.git] / gdb / sparc64fbsd-tdep.c
CommitLineData
8b39fe56
MK
1/* Target-dependent code for FreeBSD/sparc64.
2
ecd75fc8 3 Copyright (C) 2003-2014 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"
0e9f083f 31#include <string.h>
8b39fe56
MK
32
33#include "sparc64-tdep.h"
9e07977b 34#include "solib-svr4.h"
8b39fe56
MK
35
36/* From <machine/reg.h>. */
b4fd25c9 37const struct sparc_gregmap sparc64fbsd_gregmap =
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{
b4fd25c9 56 sparc64_supply_gregset (&sparc64fbsd_gregmap, 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{
b4fd25c9 64 sparc64_collect_gregset (&sparc64fbsd_gregmap, regcache, regnum, gregs);
ae036357
MK
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{
b4fd25c9 72 sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
762c360d 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{
b4fd25c9 80 sparc64_collect_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
ae036357 81}
8b39fe56
MK
82\f
83
386c036b
MK
84/* Signal trampolines. */
85
86static int
2c02bd72 87sparc64fbsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
386c036b
MK
88{
89 return (name && strcmp (name, "__sigtramp") == 0);
90}
91
92static struct sparc_frame_cache *
94afd7a6 93sparc64fbsd_sigtramp_frame_cache (struct frame_info *this_frame,
386c036b
MK
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
94afd7a6 104 cache = sparc_frame_cache (this_frame, this_cache);
386c036b
MK
105 gdb_assert (cache == *this_cache);
106
94afd7a6 107 cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
386c036b
MK
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. */
94afd7a6 112 addr = get_frame_register_unsigned (this_frame, SPARC_O2_REGNUM);
386c036b
MK
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;
94afd7a6 139 sp = get_frame_memory_unsigned (this_frame, addr, 8);
386c036b
MK
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;
94afd7a6 150 fprs = get_frame_memory_unsigned (this_frame, addr, 8);
386c036b
MK
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
94afd7a6 166sparc64fbsd_sigtramp_frame_this_id (struct frame_info *this_frame,
386c036b
MK
167 void **this_cache,
168 struct frame_id *this_id)
169{
170 struct sparc_frame_cache *cache =
94afd7a6 171 sparc64fbsd_sigtramp_frame_cache (this_frame, this_cache);
386c036b
MK
172
173 (*this_id) = frame_id_build (cache->base, cache->pc);
174}
175
94afd7a6
UW
176static struct value *
177sparc64fbsd_sigtramp_frame_prev_register (struct frame_info *this_frame,
178 void **this_cache, int regnum)
386c036b
MK
179{
180 struct sparc_frame_cache *cache =
94afd7a6 181 sparc64fbsd_sigtramp_frame_cache (this_frame, this_cache);
386c036b 182
94afd7a6 183 return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
386c036b
MK
184}
185
94afd7a6
UW
186static int
187sparc64fbsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
188 struct frame_info *this_frame,
189 void **this_cache)
386c036b 190{
94afd7a6 191 CORE_ADDR pc = get_frame_pc (this_frame);
2c02bd72 192 const char *name;
386c036b
MK
193
194 find_pc_partial_function (pc, &name, NULL, NULL);
195 if (sparc64fbsd_pc_in_sigtramp (pc, name))
94afd7a6 196 return 1;
386c036b 197
94afd7a6 198 return 0;
386c036b 199}
94afd7a6
UW
200
201static const struct frame_unwind sparc64fbsd_sigtramp_frame_unwind =
202{
203 SIGTRAMP_FRAME,
8fbca658 204 default_frame_unwind_stop_reason,
94afd7a6
UW
205 sparc64fbsd_sigtramp_frame_this_id,
206 sparc64fbsd_sigtramp_frame_prev_register,
207 NULL,
208 sparc64fbsd_sigtramp_frame_sniffer
209};
386c036b
MK
210\f
211
b13feb94
AA
212static const struct regset sparc64fbsd_gregset =
213 {
214 NULL, sparc64fbsd_supply_gregset, sparc64fbsd_collect_gregset
215 };
216
217static const struct regset sparc64fbsd_fpregset =
218 {
219 NULL, sparc64fbsd_supply_fpregset, sparc64fbsd_collect_fpregset
220 };
221
8b39fe56
MK
222static void
223sparc64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
224{
762c360d
MK
225 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
226
b13feb94 227 tdep->gregset = &sparc64fbsd_gregset;
762c360d
MK
228 tdep->sizeof_gregset = 256;
229
b13feb94 230 tdep->fpregset = &sparc64fbsd_fpregset;
762c360d
MK
231 tdep->sizeof_fpregset = 272;
232
94afd7a6 233 frame_unwind_append_unwinder (gdbarch, &sparc64fbsd_sigtramp_frame_unwind);
386c036b
MK
234
235 sparc64_init_abi (info, gdbarch);
9e07977b
MK
236
237 /* FreeBSD/sparc64 has SVR4-style shared libraries. */
238 set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
239 set_solib_svr4_fetch_link_map_offsets
240 (gdbarch, svr4_lp64_fetch_link_map_offsets);
8b39fe56
MK
241}
242
243/* Provide a prototype to silence -Wmissing-prototypes. */
244void _initialize_sparc64fbsd_tdep (void);
245
246void
247_initialize_sparc64fbsd_tdep (void)
248{
249 gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
250 GDB_OSABI_FREEBSD_ELF, sparc64fbsd_init_abi);
8b39fe56 251}
This page took 1.340239 seconds and 4 git commands to generate.