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