Remove regcache_raw_supply
[deliverable/binutils-gdb.git] / gdb / mips-nbsd-tdep.c
CommitLineData
d1180b0f
MK
1/* Target-dependent code for NetBSD/mips.
2
e2882c85 3 Copyright (C) 2002-2018 Free Software Foundation, Inc.
e4cd0d6a 4
45888261
JT
5 Contributed by Wasabi Systems, Inc.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
45888261
JT
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
45888261
JT
21
22#include "defs.h"
23#include "gdbcore.h"
24#include "regcache.h"
d1180b0f 25#include "regset.h"
45888261
JT
26#include "target.h"
27#include "value.h"
28#include "osabi.h"
29
3d9b49b0 30#include "nbsd-tdep.h"
03b62bbb 31#include "mips-nbsd-tdep.h"
1777c7b4 32#include "mips-tdep.h"
45888261
JT
33
34#include "solib-svr4.h"
35
d1180b0f
MK
36/* Shorthand for some register numbers used below. */
37#define MIPS_PC_REGNUM MIPS_EMBED_PC_REGNUM
38#define MIPS_FP0_REGNUM MIPS_EMBED_FP0_REGNUM
39#define MIPS_FSR_REGNUM MIPS_EMBED_FP0_REGNUM + 32
40
41/* Core file support. */
42
43/* Number of registers in `struct reg' from <machine/reg.h>. */
44#define MIPSNBSD_NUM_GREGS 38
45
46/* Number of registers in `struct fpreg' from <machine/reg.h>. */
47#define MIPSNBSD_NUM_FPREGS 33
48
49/* Supply register REGNUM from the buffer specified by FPREGS and LEN
50 in the floating-point register set REGSET to register cache
51 REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
52
53static void
54mipsnbsd_supply_fpregset (const struct regset *regset,
55 struct regcache *regcache,
56 int regnum, const void *fpregs, size_t len)
57{
ac7936df 58 size_t regsize = mips_isa_regsize (regcache->arch ());
19ba03f4 59 const char *regs = (const char *) fpregs;
d1180b0f
MK
60 int i;
61
62 gdb_assert (len >= MIPSNBSD_NUM_FPREGS * regsize);
63
64 for (i = MIPS_FP0_REGNUM; i <= MIPS_FSR_REGNUM; i++)
65 {
66 if (regnum == i || regnum == -1)
73e1c03f 67 regcache->raw_supply (i, regs + (i - MIPS_FP0_REGNUM) * regsize);
d1180b0f
MK
68 }
69}
70
71/* Supply register REGNUM from the buffer specified by GREGS and LEN
72 in the general-purpose register set REGSET to register cache
73 REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
74
75static void
76mipsnbsd_supply_gregset (const struct regset *regset,
77 struct regcache *regcache, int regnum,
78 const void *gregs, size_t len)
79{
ac7936df 80 size_t regsize = mips_isa_regsize (regcache->arch ());
19ba03f4 81 const char *regs = (const char *) gregs;
d1180b0f
MK
82 int i;
83
84 gdb_assert (len >= MIPSNBSD_NUM_GREGS * regsize);
85
86 for (i = 0; i <= MIPS_PC_REGNUM; i++)
87 {
88 if (regnum == i || regnum == -1)
73e1c03f 89 regcache->raw_supply (i, regs + i * regsize);
d1180b0f
MK
90 }
91
92 if (len >= (MIPSNBSD_NUM_GREGS + MIPSNBSD_NUM_FPREGS) * regsize)
93 {
94 regs += MIPSNBSD_NUM_GREGS * regsize;
95 len -= MIPSNBSD_NUM_GREGS * regsize;
96 mipsnbsd_supply_fpregset (regset, regcache, regnum, regs, len);
97 }
98}
99
100/* NetBSD/mips register sets. */
101
3ca7dae4 102static const struct regset mipsnbsd_gregset =
d1180b0f
MK
103{
104 NULL,
f962539a
AA
105 mipsnbsd_supply_gregset,
106 NULL,
107 REGSET_VARIABLE_SIZE
d1180b0f
MK
108};
109
3ca7dae4 110static const struct regset mipsnbsd_fpregset =
d1180b0f
MK
111{
112 NULL,
113 mipsnbsd_supply_fpregset
114};
115
d4036235 116/* Iterate over core file register note sections. */
d1180b0f 117
d4036235
AA
118static void
119mipsnbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
120 iterate_over_regset_sections_cb *cb,
121 void *cb_data,
122 const struct regcache *regcache)
d1180b0f
MK
123{
124 size_t regsize = mips_isa_regsize (gdbarch);
d1180b0f 125
d4036235
AA
126 cb (".reg", MIPSNBSD_NUM_GREGS * regsize, &mipsnbsd_gregset,
127 NULL, cb_data);
128 cb (".reg2", MIPSNBSD_NUM_FPREGS * regsize, &mipsnbsd_fpregset,
129 NULL, cb_data);
d1180b0f
MK
130}
131\f
132
45888261
JT
133/* Conveniently, GDB uses the same register numbering as the
134 ptrace register structure used by NetBSD/mips. */
135
136void
28f5035f 137mipsnbsd_supply_reg (struct regcache *regcache, const char *regs, int regno)
45888261 138{
ac7936df 139 struct gdbarch *gdbarch = regcache->arch ();
45888261
JT
140 int i;
141
2eb4d78b 142 for (i = 0; i <= gdbarch_pc_regnum (gdbarch); i++)
45888261
JT
143 {
144 if (regno == i || regno == -1)
145 {
2eb4d78b 146 if (gdbarch_cannot_fetch_register (gdbarch, i))
73e1c03f 147 regcache->raw_supply (i, NULL);
45888261 148 else
73e1c03f
SM
149 regcache->raw_supply
150 (i, regs + (i * mips_isa_regsize (gdbarch)));
45888261
JT
151 }
152 }
153}
154
155void
28f5035f 156mipsnbsd_fill_reg (const struct regcache *regcache, char *regs, int regno)
45888261 157{
ac7936df 158 struct gdbarch *gdbarch = regcache->arch ();
45888261
JT
159 int i;
160
2eb4d78b 161 for (i = 0; i <= gdbarch_pc_regnum (gdbarch); i++)
8d4c1ba3 162 if ((regno == i || regno == -1)
2eb4d78b 163 && ! gdbarch_cannot_store_register (gdbarch, i))
28f5035f 164 regcache_raw_collect (regcache, i,
2eb4d78b 165 regs + (i * mips_isa_regsize (gdbarch)));
45888261
JT
166}
167
168void
025bb325
MS
169mipsnbsd_supply_fpreg (struct regcache *regcache,
170 const char *fpregs, int regno)
45888261 171{
ac7936df 172 struct gdbarch *gdbarch = regcache->arch ();
45888261
JT
173 int i;
174
2eb4d78b
UW
175 for (i = gdbarch_fp0_regnum (gdbarch);
176 i <= mips_regnum (gdbarch)->fp_implementation_revision;
56cea623 177 i++)
45888261
JT
178 {
179 if (regno == i || regno == -1)
180 {
2eb4d78b 181 if (gdbarch_cannot_fetch_register (gdbarch, i))
73e1c03f 182 regcache->raw_supply (i, NULL);
45888261 183 else
73e1c03f
SM
184 regcache->raw_supply (i,
185 fpregs
2eb4d78b
UW
186 + ((i - gdbarch_fp0_regnum (gdbarch))
187 * mips_isa_regsize (gdbarch)));
45888261
JT
188 }
189 }
190}
191
192void
28f5035f 193mipsnbsd_fill_fpreg (const struct regcache *regcache, char *fpregs, int regno)
45888261 194{
ac7936df 195 struct gdbarch *gdbarch = regcache->arch ();
45888261
JT
196 int i;
197
2eb4d78b
UW
198 for (i = gdbarch_fp0_regnum (gdbarch);
199 i <= mips_regnum (gdbarch)->fp_control_status;
56cea623 200 i++)
8d4c1ba3 201 if ((regno == i || regno == -1)
2eb4d78b 202 && ! gdbarch_cannot_store_register (gdbarch, i))
28f5035f 203 regcache_raw_collect (regcache, i,
2eb4d78b
UW
204 fpregs + ((i - gdbarch_fp0_regnum (gdbarch))
205 * mips_isa_regsize (gdbarch)));
45888261
JT
206}
207
ac61d2db
SA
208#if 0
209
45888261
JT
210/* Under NetBSD/mips, signal handler invocations can be identified by the
211 designated code sequence that is used to return from a signal handler.
212 In particular, the return address of a signal handler points to the
213 following code sequence:
214
215 addu a0, sp, 16
216 li v0, 295 # __sigreturn14
217 syscall
218
219 Each instruction has a unique encoding, so we simply attempt to match
220 the instruction the PC is pointing to with any of the above instructions.
221 If there is a hit, we know the offset to the start of the designated
222 sequence and can then check whether we really are executing in the
223 signal trampoline. If not, -1 is returned, otherwise the offset from the
224 start of the return sequence is returned. */
225
226#define RETCODE_NWORDS 3
227#define RETCODE_SIZE (RETCODE_NWORDS * 4)
228
229static const unsigned char sigtramp_retcode_mipsel[RETCODE_SIZE] =
230{
231 0x10, 0x00, 0xa4, 0x27, /* addu a0, sp, 16 */
232 0x27, 0x01, 0x02, 0x24, /* li v0, 295 */
233 0x0c, 0x00, 0x00, 0x00, /* syscall */
234};
235
236static const unsigned char sigtramp_retcode_mipseb[RETCODE_SIZE] =
237{
238 0x27, 0xa4, 0x00, 0x10, /* addu a0, sp, 16 */
239 0x24, 0x02, 0x01, 0x27, /* li v0, 295 */
240 0x00, 0x00, 0x00, 0x0c, /* syscall */
241};
242
ac61d2db
SA
243#endif
244
45888261 245/* Figure out where the longjmp will land. We expect that we have
4c7d22cb
MK
246 just entered longjmp and haven't yet setup the stack frame, so the
247 args are still in the argument regs. MIPS_A0_REGNUM points at the
45888261
JT
248 jmp_buf structure from which we extract the PC that we will land
249 at. The PC is copied into *pc. This routine returns true on
250 success. */
251
252#define NBSD_MIPS_JB_PC (2 * 4)
74ed0bb4
MD
253#define NBSD_MIPS_JB_ELEMENT_SIZE(gdbarch) mips_isa_regsize (gdbarch)
254#define NBSD_MIPS_JB_OFFSET(gdbarch) (NBSD_MIPS_JB_PC * \
255 NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch))
45888261
JT
256
257static int
60ade65d 258mipsnbsd_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
45888261 259{
74ed0bb4 260 struct gdbarch *gdbarch = get_frame_arch (frame);
e17a4113 261 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
45888261 262 CORE_ADDR jb_addr;
948f8e3d 263 gdb_byte *buf;
45888261 264
224c3ddb 265 buf = (gdb_byte *) alloca (NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch));
45888261 266
60ade65d 267 jb_addr = get_frame_register_unsigned (frame, MIPS_A0_REGNUM);
45888261 268
74ed0bb4
MD
269 if (target_read_memory (jb_addr + NBSD_MIPS_JB_OFFSET (gdbarch), buf,
270 NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch)))
45888261
JT
271 return 0;
272
e17a4113
UW
273 *pc = extract_unsigned_integer (buf, NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch),
274 byte_order);
45888261
JT
275 return 1;
276}
277
278static int
64a3914f 279mipsnbsd_cannot_fetch_register (struct gdbarch *gdbarch, int regno)
45888261 280{
4c7d22cb 281 return (regno == MIPS_ZERO_REGNUM
64a3914f 282 || regno == mips_regnum (gdbarch)->fp_implementation_revision);
45888261
JT
283}
284
285static int
64a3914f 286mipsnbsd_cannot_store_register (struct gdbarch *gdbarch, int regno)
45888261 287{
4c7d22cb 288 return (regno == MIPS_ZERO_REGNUM
64a3914f 289 || regno == mips_regnum (gdbarch)->fp_implementation_revision);
45888261
JT
290}
291
fabe86c8
MK
292/* Shared library support. */
293
294/* NetBSD/mips uses a slightly different `struct link_map' than the
45888261 295 other NetBSD platforms. */
fabe86c8 296
45888261 297static struct link_map_offsets *
fabe86c8 298mipsnbsd_ilp32_fetch_link_map_offsets (void)
45888261
JT
299{
300 static struct link_map_offsets lmo;
301 static struct link_map_offsets *lmp = NULL;
302
303 if (lmp == NULL)
304 {
305 lmp = &lmo;
306
e4cd0d6a
MK
307 lmo.r_version_offset = 0;
308 lmo.r_version_size = 4;
45888261 309 lmo.r_map_offset = 4;
7cd25cfc 310 lmo.r_brk_offset = 8;
e4cd0d6a 311 lmo.r_ldsomap_offset = -1;
45888261 312
fabe86c8 313 /* Everything we need is in the first 24 bytes. */
45888261 314 lmo.link_map_size = 24;
4c7d22cb 315 lmo.l_addr_offset = 4;
45888261 316 lmo.l_name_offset = 8;
cc10cae3 317 lmo.l_ld_offset = 12;
45888261 318 lmo.l_next_offset = 16;
45888261 319 lmo.l_prev_offset = 20;
45888261
JT
320 }
321
322 return lmp;
323}
324
325static struct link_map_offsets *
fabe86c8 326mipsnbsd_lp64_fetch_link_map_offsets (void)
45888261
JT
327{
328 static struct link_map_offsets lmo;
329 static struct link_map_offsets *lmp = NULL;
330
331 if (lmp == NULL)
332 {
333 lmp = &lmo;
334
e4cd0d6a
MK
335 lmo.r_version_offset = 0;
336 lmo.r_version_size = 4;
337 lmo.r_map_offset = 8;
7cd25cfc 338 lmo.r_brk_offset = 16;
e4cd0d6a 339 lmo.r_ldsomap_offset = -1;
45888261 340
fabe86c8 341 /* Everything we need is in the first 40 bytes. */
45888261 342 lmo.link_map_size = 48;
45888261 343 lmo.l_addr_offset = 0;
45888261 344 lmo.l_name_offset = 16;
cc10cae3 345 lmo.l_ld_offset = 24;
45888261 346 lmo.l_next_offset = 32;
45888261 347 lmo.l_prev_offset = 40;
45888261
JT
348 }
349
350 return lmp;
351}
fabe86c8 352\f
45888261
JT
353
354static void
355mipsnbsd_init_abi (struct gdbarch_info info,
356 struct gdbarch *gdbarch)
357{
d4036235
AA
358 set_gdbarch_iterate_over_regset_sections
359 (gdbarch, mipsnbsd_iterate_over_regset_sections);
d1180b0f 360
45888261
JT
361 set_gdbarch_get_longjmp_target (gdbarch, mipsnbsd_get_longjmp_target);
362
363 set_gdbarch_cannot_fetch_register (gdbarch, mipsnbsd_cannot_fetch_register);
364 set_gdbarch_cannot_store_register (gdbarch, mipsnbsd_cannot_store_register);
365
366 set_gdbarch_software_single_step (gdbarch, mips_software_single_step);
367
fabe86c8
MK
368 /* NetBSD/mips has SVR4-style shared libraries. */
369 set_solib_svr4_fetch_link_map_offsets
370 (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32 ?
371 mipsnbsd_ilp32_fetch_link_map_offsets :
372 mipsnbsd_lp64_fetch_link_map_offsets));
45888261 373}
63807e1d 374
45888261
JT
375void
376_initialize_mipsnbsd_tdep (void)
377{
1736a7bd 378 gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_NETBSD,
45888261 379 mipsnbsd_init_abi);
45888261 380}
This page took 1.426649 seconds and 4 git commands to generate.