Automatic date update in version.in
[deliverable/binutils-gdb.git] / gdb / sparc64-netbsd-tdep.c
CommitLineData
386c036b
MK
1/* Target-dependent code for NetBSD/sparc64.
2
3666a048 3 Copyright (C) 2002-2021 Free Software Foundation, Inc.
386c036b
MK
4 Based on code contributed by Wasabi Systems, Inc.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
386c036b
MK
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
386c036b
MK
20
21#include "defs.h"
22#include "frame.h"
23#include "frame-unwind.h"
24#include "gdbcore.h"
25#include "osabi.h"
26#include "regcache.h"
2ca62865 27#include "regset.h"
386c036b 28#include "symtab.h"
3510d1f2 29#include "objfiles.h"
386c036b
MK
30#include "solib-svr4.h"
31#include "trad-frame.h"
32
386c036b 33#include "sparc64-tdep.h"
1b71cfcf 34#include "netbsd-tdep.h"
386c036b
MK
35
36/* From <machine/reg.h>. */
b4fd25c9 37const struct sparc_gregmap sparc64nbsd_gregmap =
386c036b
MK
38{
39 0 * 8, /* "tstate" */
40 1 * 8, /* %pc */
41 2 * 8, /* %npc */
42 3 * 8, /* %y */
43 -1, /* %fprs */
44 -1,
45 5 * 8, /* %g1 */
46 -1, /* %l0 */
47 4 /* sizeof (%y) */
48};
2ca62865 49\f
386c036b
MK
50
51static void
2ca62865
MK
52sparc64nbsd_supply_gregset (const struct regset *regset,
53 struct regcache *regcache,
54 int regnum, const void *gregs, size_t len)
386c036b 55{
b4fd25c9 56 sparc64_supply_gregset (&sparc64nbsd_gregmap, regcache, regnum, gregs);
386c036b
MK
57}
58
2ca62865
MK
59static void
60sparc64nbsd_supply_fpregset (const struct regset *regset,
61 struct regcache *regcache,
62 int regnum, const void *fpregs, size_t len)
386c036b 63{
b4fd25c9 64 sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
2ca62865 65}
386c036b 66\f
2ca62865 67
386c036b
MK
68/* Signal trampolines. */
69
70/* The following variables describe the location of an on-stack signal
71 trampoline. The current values correspond to the memory layout for
72 NetBSD 1.3 and up. These shouldn't be necessary for NetBSD 2.0 and
73 up, since NetBSD uses signal trampolines provided by libc now. */
74
75static const CORE_ADDR sparc64nbsd_sigtramp_start = 0xffffffffffffdee4ULL;
76static const CORE_ADDR sparc64nbsd_sigtramp_end = 0xffffffffffffe000ULL;
77
78static int
2c02bd72 79sparc64nbsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
386c036b
MK
80{
81 if (pc >= sparc64nbsd_sigtramp_start && pc < sparc64nbsd_sigtramp_end)
82 return 1;
83
84 return nbsd_pc_in_sigtramp (pc, name);
85}
86
098caef4 87trad_frame_saved_reg *
1e067c66 88sparc64nbsd_sigcontext_saved_regs (CORE_ADDR sigcontext_addr,
94afd7a6 89 struct frame_info *this_frame)
386c036b 90{
e17a4113 91 struct gdbarch *gdbarch = get_frame_arch (this_frame);
098caef4 92 trad_frame_saved_reg *saved_regs;
1e067c66 93 CORE_ADDR addr, sp;
386c036b
MK
94 int regnum, delta;
95
94afd7a6 96 saved_regs = trad_frame_alloc_saved_regs (this_frame);
386c036b
MK
97
98 /* The registers are saved in bits and pieces scattered all over the
99 place. The code below records their location on the assumption
100 that the part of the signal trampoline that saves the state has
101 been executed. */
102
098caef4
LM
103 saved_regs[SPARC_SP_REGNUM].set_addr (sigcontext_addr + 8);
104 saved_regs[SPARC64_PC_REGNUM].set_addr (sigcontext_addr + 16);
105 saved_regs[SPARC64_NPC_REGNUM].set_addr (sigcontext_addr + 24);
106 saved_regs[SPARC64_STATE_REGNUM].set_addr (sigcontext_addr + 32);
107 saved_regs[SPARC_G1_REGNUM].set_addr (sigcontext_addr + 40);
108 saved_regs[SPARC_O0_REGNUM].set_addr (sigcontext_addr + 48);
386c036b
MK
109
110 /* The remaining `global' registers and %y are saved in the `local'
111 registers. */
112 delta = SPARC_L0_REGNUM - SPARC_G0_REGNUM;
113 for (regnum = SPARC_G2_REGNUM; regnum <= SPARC_G7_REGNUM; regnum++)
098caef4
LM
114 saved_regs[regnum].set_realreg (regnum + delta);
115 saved_regs[SPARC64_Y_REGNUM].set_realreg (SPARC_L1_REGNUM);
386c036b
MK
116
117 /* The remaining `out' registers can be found in the current frame's
118 `in' registers. */
119 delta = SPARC_I0_REGNUM - SPARC_O0_REGNUM;
120 for (regnum = SPARC_O1_REGNUM; regnum <= SPARC_O5_REGNUM; regnum++)
098caef4
LM
121 saved_regs[regnum].set_realreg (regnum + delta);
122 saved_regs[SPARC_O7_REGNUM].set_realreg (SPARC_I7_REGNUM);
386c036b
MK
123
124 /* The `local' and `in' registers have been saved in the register
125 save area. */
098caef4 126 addr = saved_regs[SPARC_SP_REGNUM].addr ();
94afd7a6 127 sp = get_frame_memory_unsigned (this_frame, addr, 8);
386c036b
MK
128 for (regnum = SPARC_L0_REGNUM, addr = sp + BIAS;
129 regnum <= SPARC_I7_REGNUM; regnum++, addr += 8)
098caef4 130 saved_regs[regnum].set_addr (addr);
386c036b 131
8391b9b1
MK
132 /* Handle StackGhost. */
133 {
e17a4113 134 ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);
8391b9b1
MK
135
136 if (wcookie != 0)
137 {
138 ULONGEST i7;
139
098caef4 140 addr = saved_regs[SPARC_I7_REGNUM].addr ();
94afd7a6 141 i7 = get_frame_memory_unsigned (this_frame, addr, 8);
a9a87d35 142 saved_regs[SPARC_I7_REGNUM].set_value (i7 ^ wcookie);
8391b9b1
MK
143 }
144 }
145
386c036b
MK
146 /* TODO: Handle the floating-point registers. */
147
1e067c66
MK
148 return saved_regs;
149}
150
151static struct sparc_frame_cache *
94afd7a6 152sparc64nbsd_sigcontext_frame_cache (struct frame_info *this_frame,
1e067c66
MK
153 void **this_cache)
154{
155 struct sparc_frame_cache *cache;
156 CORE_ADDR addr;
157
158 if (*this_cache)
19ba03f4 159 return (struct sparc_frame_cache *) *this_cache;
1e067c66 160
94afd7a6 161 cache = sparc_frame_cache (this_frame, this_cache);
1e067c66
MK
162 gdb_assert (cache == *this_cache);
163
164 /* If we couldn't find the frame's function, we're probably dealing
165 with an on-stack signal trampoline. */
166 if (cache->pc == 0)
167 {
168 cache->pc = sparc64nbsd_sigtramp_start;
169
170 /* Since we couldn't find the frame's function, the cache was
dda83cd7 171 initialized under the assumption that we're frameless. */
369c397b 172 sparc_record_save_insn (cache);
94afd7a6 173 addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
5b2d44a0
MK
174 if (addr & 1)
175 addr += BIAS;
1e067c66
MK
176 cache->base = addr;
177 }
178
179 /* We find the appropriate instance of `struct sigcontext' at a
180 fixed offset in the signal frame. */
5b2d44a0 181 addr = cache->base + 128 + 8;
94afd7a6 182 cache->saved_regs = sparc64nbsd_sigcontext_saved_regs (addr, this_frame);
1e067c66 183
386c036b
MK
184 return cache;
185}
186
187static void
94afd7a6 188sparc64nbsd_sigcontext_frame_this_id (struct frame_info *this_frame,
386c036b
MK
189 void **this_cache,
190 struct frame_id *this_id)
191{
192 struct sparc_frame_cache *cache =
94afd7a6 193 sparc64nbsd_sigcontext_frame_cache (this_frame, this_cache);
386c036b
MK
194
195 (*this_id) = frame_id_build (cache->base, cache->pc);
196}
197
94afd7a6
UW
198static struct value *
199sparc64nbsd_sigcontext_frame_prev_register (struct frame_info *this_frame,
200 void **this_cache, int regnum)
386c036b
MK
201{
202 struct sparc_frame_cache *cache =
94afd7a6 203 sparc64nbsd_sigcontext_frame_cache (this_frame, this_cache);
386c036b 204
94afd7a6 205 return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
386c036b
MK
206}
207
94afd7a6
UW
208static int
209sparc64nbsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
210 struct frame_info *this_frame,
211 void **this_cache)
386c036b 212{
94afd7a6 213 CORE_ADDR pc = get_frame_pc (this_frame);
2c02bd72 214 const char *name;
386c036b
MK
215
216 find_pc_partial_function (pc, &name, NULL, NULL);
217 if (sparc64nbsd_pc_in_sigtramp (pc, name))
218 {
61012eef 219 if (name == NULL || !startswith (name, "__sigtramp_sigcontext"))
94afd7a6 220 return 1;
386c036b
MK
221 }
222
94afd7a6 223 return 0;
386c036b 224}
94afd7a6
UW
225
226static const struct frame_unwind sparc64nbsd_sigcontext_frame_unwind =
227{
a154d838 228 "sparc64 netbsd sigcontext",
94afd7a6 229 SIGTRAMP_FRAME,
8fbca658 230 default_frame_unwind_stop_reason,
94afd7a6
UW
231 sparc64nbsd_sigcontext_frame_this_id,
232 sparc64nbsd_sigcontext_frame_prev_register,
233 NULL,
234 sparc64nbsd_sigtramp_frame_sniffer
235};
386c036b
MK
236\f
237
b13feb94
AA
238static const struct regset sparc64nbsd_gregset =
239 {
240 NULL, sparc64nbsd_supply_gregset, NULL
241 };
242
243static const struct regset sparc64nbsd_fpregset =
244 {
245 NULL, sparc64nbsd_supply_fpregset, NULL
246 };
247
386c036b
MK
248static void
249sparc64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
250{
2ca62865
MK
251 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
252
79743962
KR
253 nbsd_init_abi (info, gdbarch);
254
b13feb94 255 tdep->gregset = &sparc64nbsd_gregset;
2ca62865
MK
256 tdep->sizeof_gregset = 160;
257
b13feb94 258 tdep->fpregset = &sparc64nbsd_fpregset;
2ca62865
MK
259 tdep->sizeof_fpregset = 272;
260
c893be75
MK
261 /* Make sure we can single-step "new" syscalls. */
262 tdep->step_trap = sparcnbsd_step_trap;
263
94afd7a6 264 frame_unwind_append_unwinder (gdbarch, &sparc64nbsd_sigcontext_frame_unwind);
386c036b
MK
265
266 sparc64_init_abi (info, gdbarch);
267
5b2d44a0 268 /* NetBSD/sparc64 has SVR4-style shared libraries. */
3510d1f2 269 set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
386c036b 270 set_solib_svr4_fetch_link_map_offsets
3510d1f2 271 (gdbarch, svr4_lp64_fetch_link_map_offsets);
386c036b 272}
386c036b 273
6c265988 274void _initialize_sparc64nbsd_tdep ();
386c036b 275void
6c265988 276_initialize_sparc64nbsd_tdep ()
386c036b
MK
277{
278 gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
1736a7bd 279 GDB_OSABI_NETBSD, sparc64nbsd_init_abi);
386c036b 280}
This page took 2.269043 seconds and 4 git commands to generate.