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