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