gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / sparc-nbsd-tdep.c
CommitLineData
386c036b
MK
1/* Target-dependent code for NetBSD/sparc.
2
b811d2c2 3 Copyright (C) 2002-2020 Free Software Foundation, Inc.
9ce5c36a
JT
4 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
9ce5c36a
JT
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/>. */
9ce5c36a
JT
20
21#include "defs.h"
386c036b
MK
22#include "frame.h"
23#include "frame-unwind.h"
9ce5c36a 24#include "gdbcore.h"
3e461478 25#include "gdbtypes.h"
9ce5c36a 26#include "osabi.h"
386c036b 27#include "regcache.h"
4e7b0cd3 28#include "regset.h"
386c036b
MK
29#include "solib-svr4.h"
30#include "symtab.h"
31#include "trad-frame.h"
0d12e84c 32#include "gdbarch.h"
9ce5c36a 33
c139e7d9 34#include "sparc-tdep.h"
9ce5c36a
JT
35#include "nbsd-tdep.h"
36
c893be75
MK
37/* Macros to extract fields from SPARC instructions. */
38#define X_RS1(i) (((i) >> 14) & 0x1f)
39#define X_RS2(i) ((i) & 0x1f)
40#define X_I(i) (((i) >> 13) & 1)
41
b4fd25c9 42const struct sparc_gregmap sparc32nbsd_gregmap =
9ce5c36a 43{
386c036b
MK
44 0 * 4, /* %psr */
45 1 * 4, /* %pc */
46 2 * 4, /* %npc */
47 3 * 4, /* %y */
48 -1, /* %wim */
49 -1, /* %tbr */
50 5 * 4, /* %g1 */
51 -1 /* %l0 */
52};
9ce5c36a 53
9ce5c36a 54static void
4e7b0cd3
MK
55sparc32nbsd_supply_gregset (const struct regset *regset,
56 struct regcache *regcache,
57 int regnum, const void *gregs, size_t len)
9ce5c36a 58{
b4fd25c9 59 sparc32_supply_gregset (&sparc32nbsd_gregmap, regcache, regnum, gregs);
c8e737d5
MK
60
61 /* Traditional NetBSD core files don't use multiple register sets.
62 Instead, the general-purpose and floating-point registers are
63 lumped together in a single section. */
64 if (len >= 212)
b4fd25c9 65 sparc32_supply_fpregset (&sparc32_bsd_fpregmap, regcache, regnum,
db75c717 66 (const char *) gregs + 80);
9ce5c36a
JT
67}
68
4e7b0cd3
MK
69static void
70sparc32nbsd_supply_fpregset (const struct regset *regset,
71 struct regcache *regcache,
72 int regnum, const void *fpregs, size_t len)
9ce5c36a 73{
b4fd25c9 74 sparc32_supply_fpregset (&sparc32_bsd_fpregmap, regcache, regnum, fpregs);
4e7b0cd3 75}
9ce5c36a 76
386c036b
MK
77\f
78/* Signal trampolines. */
79
80/* The following variables describe the location of an on-stack signal
81 trampoline. The current values correspond to the memory layout for
82 NetBSD 1.3 and up. These shouldn't be necessary for NetBSD 2.0 and
83 up, since NetBSD uses signal trampolines provided by libc now. */
9ce5c36a 84
386c036b
MK
85static const CORE_ADDR sparc32nbsd_sigtramp_start = 0xeffffef0;
86static const CORE_ADDR sparc32nbsd_sigtramp_end = 0xeffffff0;
9ce5c36a
JT
87
88static int
2c02bd72 89sparc32nbsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
386c036b
MK
90{
91 if (pc >= sparc32nbsd_sigtramp_start && pc < sparc32nbsd_sigtramp_end)
92 return 1;
93
94 return nbsd_pc_in_sigtramp (pc, name);
95}
96
566626fa 97struct trad_frame_saved_reg *
7ea566be 98sparc32nbsd_sigcontext_saved_regs (struct frame_info *this_frame)
9ce5c36a 99{
e17a4113 100 struct gdbarch *gdbarch = get_frame_arch (this_frame);
566626fa 101 struct trad_frame_saved_reg *saved_regs;
386c036b 102 CORE_ADDR addr, sigcontext_addr;
386c036b 103 int regnum, delta;
566626fa 104 ULONGEST psr;
9ce5c36a 105
7ea566be 106 saved_regs = trad_frame_alloc_saved_regs (this_frame);
9ce5c36a 107
566626fa
MK
108 /* We find the appropriate instance of `struct sigcontext' at a
109 fixed offset in the signal frame. */
7ea566be 110 addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
566626fa 111 sigcontext_addr = addr + 64 + 16;
9ce5c36a 112
386c036b
MK
113 /* The registers are saved in bits and pieces scattered all over the
114 place. The code below records their location on the assumption
115 that the part of the signal trampoline that saves the state has
116 been executed. */
9ce5c36a 117
566626fa
MK
118 saved_regs[SPARC_SP_REGNUM].addr = sigcontext_addr + 8;
119 saved_regs[SPARC32_PC_REGNUM].addr = sigcontext_addr + 12;
120 saved_regs[SPARC32_NPC_REGNUM].addr = sigcontext_addr + 16;
121 saved_regs[SPARC32_PSR_REGNUM].addr = sigcontext_addr + 20;
122 saved_regs[SPARC_G1_REGNUM].addr = sigcontext_addr + 24;
123 saved_regs[SPARC_O0_REGNUM].addr = sigcontext_addr + 28;
386c036b
MK
124
125 /* The remaining `global' registers and %y are saved in the `local'
126 registers. */
127 delta = SPARC_L0_REGNUM - SPARC_G0_REGNUM;
128 for (regnum = SPARC_G2_REGNUM; regnum <= SPARC_G7_REGNUM; regnum++)
566626fa
MK
129 saved_regs[regnum].realreg = regnum + delta;
130 saved_regs[SPARC32_Y_REGNUM].realreg = SPARC_L1_REGNUM;
386c036b
MK
131
132 /* The remaining `out' registers can be found in the current frame's
133 `in' registers. */
134 delta = SPARC_I0_REGNUM - SPARC_O0_REGNUM;
135 for (regnum = SPARC_O1_REGNUM; regnum <= SPARC_O5_REGNUM; regnum++)
566626fa
MK
136 saved_regs[regnum].realreg = regnum + delta;
137 saved_regs[SPARC_O7_REGNUM].realreg = SPARC_I7_REGNUM;
386c036b
MK
138
139 /* The `local' and `in' registers have been saved in the register
140 save area. */
566626fa 141 addr = saved_regs[SPARC_SP_REGNUM].addr;
7ea566be 142 addr = get_frame_memory_unsigned (this_frame, addr, 4);
386c036b
MK
143 for (regnum = SPARC_L0_REGNUM;
144 regnum <= SPARC_I7_REGNUM; regnum++, addr += 4)
566626fa 145 saved_regs[regnum].addr = addr;
386c036b 146
1c800673
MK
147 /* Handle StackGhost. */
148 {
e17a4113 149 ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);
1c800673
MK
150
151 if (wcookie != 0)
152 {
153 ULONGEST i7;
154
155 addr = saved_regs[SPARC_I7_REGNUM].addr;
7ea566be 156 i7 = get_frame_memory_unsigned (this_frame, addr, 4);
1c800673
MK
157 trad_frame_set_value (saved_regs, SPARC_I7_REGNUM, i7 ^ wcookie);
158 }
159 }
160
386c036b
MK
161 /* The floating-point registers are only saved if the EF bit in %prs
162 has been set. */
163
164#define PSR_EF 0x00001000
165
566626fa 166 addr = saved_regs[SPARC32_PSR_REGNUM].addr;
7ea566be 167 psr = get_frame_memory_unsigned (this_frame, addr, 4);
386c036b
MK
168 if (psr & PSR_EF)
169 {
170 CORE_ADDR sp;
171
7ea566be 172 sp = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
566626fa 173 saved_regs[SPARC32_FSR_REGNUM].addr = sp + 96;
386c036b
MK
174 for (regnum = SPARC_F0_REGNUM, addr = sp + 96 + 8;
175 regnum <= SPARC_F31_REGNUM; regnum++, addr += 4)
566626fa
MK
176 saved_regs[regnum].addr = addr;
177 }
178
179 return saved_regs;
180}
181
182static struct sparc_frame_cache *
7ea566be 183sparc32nbsd_sigcontext_frame_cache (struct frame_info *this_frame,
566626fa
MK
184 void **this_cache)
185{
186 struct sparc_frame_cache *cache;
187 CORE_ADDR addr;
188
189 if (*this_cache)
19ba03f4 190 return (struct sparc_frame_cache *) *this_cache;
566626fa 191
7ea566be 192 cache = sparc_frame_cache (this_frame, this_cache);
566626fa
MK
193 gdb_assert (cache == *this_cache);
194
195 /* If we couldn't find the frame's function, we're probably dealing
196 with an on-stack signal trampoline. */
197 if (cache->pc == 0)
198 {
199 cache->pc = sparc32nbsd_sigtramp_start;
200
201 /* Since we couldn't find the frame's function, the cache was
202 initialized under the assumption that we're frameless. */
369c397b 203 sparc_record_save_insn (cache);
7ea566be 204 addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
566626fa 205 cache->base = addr;
386c036b
MK
206 }
207
7ea566be 208 cache->saved_regs = sparc32nbsd_sigcontext_saved_regs (this_frame);
566626fa 209
386c036b 210 return cache;
9ce5c36a
JT
211}
212
386c036b 213static void
7ea566be 214sparc32nbsd_sigcontext_frame_this_id (struct frame_info *this_frame,
386c036b
MK
215 void **this_cache,
216 struct frame_id *this_id)
217{
218 struct sparc_frame_cache *cache =
7ea566be 219 sparc32nbsd_sigcontext_frame_cache (this_frame, this_cache);
386c036b
MK
220
221 (*this_id) = frame_id_build (cache->base, cache->pc);
222}
223
7ea566be
MK
224static struct value *
225sparc32nbsd_sigcontext_frame_prev_register (struct frame_info *this_frame,
226 void **this_cache, int regnum)
9ce5c36a 227{
386c036b 228 struct sparc_frame_cache *cache =
7ea566be 229 sparc32nbsd_sigcontext_frame_cache (this_frame, this_cache);
9ce5c36a 230
7ea566be 231 return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
386c036b 232}
9ce5c36a 233
7ea566be
MK
234static int
235sparc32nbsd_sigcontext_frame_sniffer (const struct frame_unwind *self,
236 struct frame_info *this_frame,
237 void **this_cache)
386c036b 238{
7ea566be 239 CORE_ADDR pc = get_frame_pc (this_frame);
2c02bd72 240 const char *name;
9ce5c36a 241
386c036b
MK
242 find_pc_partial_function (pc, &name, NULL, NULL);
243 if (sparc32nbsd_pc_in_sigtramp (pc, name))
244 {
61012eef 245 if (name == NULL || !startswith (name, "__sigtramp_sigcontext"))
7ea566be 246 return 1;
386c036b
MK
247 }
248
7ea566be 249 return 0;
9ce5c36a 250}
7ea566be
MK
251
252static const struct frame_unwind sparc32nbsd_sigcontext_frame_unwind =
253{
254 SIGTRAMP_FRAME,
8fbca658 255 default_frame_unwind_stop_reason,
7ea566be
MK
256 sparc32nbsd_sigcontext_frame_this_id,
257 sparc32nbsd_sigcontext_frame_prev_register,
258 NULL,
259 sparc32nbsd_sigcontext_frame_sniffer
260};
386c036b 261\f
c893be75
MK
262/* Return the address of a system call's alternative return
263 address. */
264
265CORE_ADDR
0b1b3e42 266sparcnbsd_step_trap (struct frame_info *frame, unsigned long insn)
c893be75
MK
267{
268 if ((X_I (insn) == 0 && X_RS1 (insn) == 0 && X_RS2 (insn) == 0)
269 || (X_I (insn) == 1 && X_RS1 (insn) == 0 && (insn & 0x7f) == 0))
270 {
271 /* "New" system call. */
0b1b3e42 272 ULONGEST number = get_frame_register_unsigned (frame, SPARC_G1_REGNUM);
c893be75
MK
273
274 if (number & 0x400)
0b1b3e42 275 return get_frame_register_unsigned (frame, SPARC_G2_REGNUM);
c893be75 276 if (number & 0x800)
0b1b3e42 277 return get_frame_register_unsigned (frame, SPARC_G7_REGNUM);
c893be75
MK
278 }
279
280 return 0;
281}
282\f
386c036b 283
b13feb94
AA
284static const struct regset sparc32nbsd_gregset =
285 {
286 NULL, sparc32nbsd_supply_gregset, NULL
287 };
288
289static const struct regset sparc32nbsd_fpregset =
290 {
291 NULL, sparc32nbsd_supply_fpregset, NULL
292 };
293
1736a7bd 294void
386c036b 295sparc32nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
9ce5c36a 296{
4e7b0cd3
MK
297 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
298
79743962
KR
299 nbsd_init_abi (info, gdbarch);
300
386c036b
MK
301 /* NetBSD doesn't support the 128-bit `long double' from the psABI. */
302 set_gdbarch_long_double_bit (gdbarch, 64);
8da61cc4 303 set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
386c036b 304
b13feb94 305 tdep->gregset = &sparc32nbsd_gregset;
c8e737d5 306 tdep->sizeof_gregset = 20 * 4;
4e7b0cd3 307
b13feb94 308 tdep->fpregset = &sparc32nbsd_fpregset;
c8e737d5 309 tdep->sizeof_fpregset = 33 * 4;
4e7b0cd3 310
c893be75
MK
311 /* Make sure we can single-step "new" syscalls. */
312 tdep->step_trap = sparcnbsd_step_trap;
313
7ea566be 314 frame_unwind_append_unwinder (gdbarch, &sparc32nbsd_sigcontext_frame_unwind);
9ce5c36a 315
386c036b 316 set_solib_svr4_fetch_link_map_offsets
be24b061 317 (gdbarch, svr4_ilp32_fetch_link_map_offsets);
9ce5c36a
JT
318}
319
6c265988 320void _initialize_sparcnbsd_tdep ();
9ce5c36a 321void
6c265988 322_initialize_sparcnbsd_tdep ()
9ce5c36a 323{
1736a7bd
PA
324 gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_NETBSD,
325 sparc32nbsd_init_abi);
9ce5c36a 326}
This page took 1.872413 seconds and 4 git commands to generate.