Allow integer immediate for VFP vmov instructions.
[deliverable/binutils-gdb.git] / gdb / arm-nbsd-nat.c
CommitLineData
e7a42bc8 1/* Native-dependent code for BSD Unix running on ARM's, for GDB.
9f8e0089 2
e2882c85 3 Copyright (C) 1988-2018 Free Software Foundation, Inc.
e7a42bc8
FN
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
e7a42bc8
FN
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/>. */
e7a42bc8
FN
19
20#include "defs.h"
2b73aeb1
MK
21#include "gdbcore.h"
22#include "inferior.h"
23#include "regcache.h"
24#include "target.h"
e7a42bc8
FN
25#include <sys/types.h>
26#include <sys/ptrace.h>
27#include <machine/reg.h>
28#include <machine/frame.h>
2b73aeb1
MK
29
30#include "arm-tdep.h"
31#include "inf-ptrace.h"
e7a42bc8 32
f6ac5f3d
PA
33class arm_netbsd_nat_target final : public inf_ptrace_target
34{
35public:
36 /* Add our register access methods. */
37 void fetch_registers (struct regcache *, int) override;
38 void store_registers (struct regcache *, int) override;
39};
40
41static arm_netbsd_nat_target the_arm_netbsd_nat_target;
42
47221191
RE
43extern int arm_apcs_32;
44
b34db576 45static void
d683e2b7 46arm_supply_gregset (struct regcache *regcache, struct reg *gregset)
b34db576
RE
47{
48 int regno;
49 CORE_ADDR r_pc;
50
51 /* Integer registers. */
52 for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
d683e2b7 53 regcache_raw_supply (regcache, regno, (char *) &gregset->r[regno]);
b34db576 54
d683e2b7 55 regcache_raw_supply (regcache, ARM_SP_REGNUM,
23a6d369 56 (char *) &gregset->r_sp);
d683e2b7 57 regcache_raw_supply (regcache, ARM_LR_REGNUM,
23a6d369 58 (char *) &gregset->r_lr);
b34db576 59 /* This is ok: we're running native... */
ac7936df 60 r_pc = gdbarch_addr_bits_remove (regcache->arch (), gregset->r_pc);
d683e2b7 61 regcache_raw_supply (regcache, ARM_PC_REGNUM, (char *) &r_pc);
b34db576
RE
62
63 if (arm_apcs_32)
d683e2b7 64 regcache_raw_supply (regcache, ARM_PS_REGNUM,
23a6d369 65 (char *) &gregset->r_cpsr);
b34db576 66 else
d683e2b7 67 regcache_raw_supply (regcache, ARM_PS_REGNUM,
23a6d369 68 (char *) &gregset->r_pc);
b34db576
RE
69}
70
71static void
d683e2b7 72arm_supply_fparegset (struct regcache *regcache, struct fpreg *fparegset)
b34db576
RE
73{
74 int regno;
75
76 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
d683e2b7 77 regcache_raw_supply (regcache, regno,
23a6d369 78 (char *) &fparegset->fpr[regno - ARM_F0_REGNUM]);
b34db576 79
d683e2b7 80 regcache_raw_supply (regcache, ARM_FPS_REGNUM,
23a6d369 81 (char *) &fparegset->fpr_fpsr);
b34db576
RE
82}
83
47221191 84static void
56be3814 85fetch_register (struct regcache *regcache, int regno)
47221191
RE
86{
87 struct reg inferior_registers;
88 int ret;
89
9ac8a7c2 90 ret = ptrace (PT_GETREGS, ptid_get_pid (regcache_get_ptid (regcache)),
9f8e0089 91 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
47221191
RE
92
93 if (ret < 0)
94 {
edefbb7c 95 warning (_("unable to fetch general register"));
47221191
RE
96 return;
97 }
98
99 switch (regno)
100 {
101 case ARM_SP_REGNUM:
56be3814 102 regcache_raw_supply (regcache, ARM_SP_REGNUM,
23a6d369 103 (char *) &inferior_registers.r_sp);
47221191
RE
104 break;
105
106 case ARM_LR_REGNUM:
56be3814 107 regcache_raw_supply (regcache, ARM_LR_REGNUM,
23a6d369 108 (char *) &inferior_registers.r_lr);
47221191
RE
109 break;
110
111 case ARM_PC_REGNUM:
0963b4bd 112 /* This is ok: we're running native... */
bf6ae464 113 inferior_registers.r_pc = gdbarch_addr_bits_remove
ac7936df 114 (regcache->arch (),
b2cb219a 115 inferior_registers.r_pc);
56be3814 116 regcache_raw_supply (regcache, ARM_PC_REGNUM,
23a6d369 117 (char *) &inferior_registers.r_pc);
47221191
RE
118 break;
119
120 case ARM_PS_REGNUM:
121 if (arm_apcs_32)
56be3814 122 regcache_raw_supply (regcache, ARM_PS_REGNUM,
23a6d369 123 (char *) &inferior_registers.r_cpsr);
47221191 124 else
56be3814 125 regcache_raw_supply (regcache, ARM_PS_REGNUM,
23a6d369 126 (char *) &inferior_registers.r_pc);
47221191
RE
127 break;
128
129 default:
56be3814 130 regcache_raw_supply (regcache, regno,
23a6d369 131 (char *) &inferior_registers.r[regno]);
47221191
RE
132 break;
133 }
134}
135
136static void
56be3814 137fetch_regs (struct regcache *regcache)
e7a42bc8
FN
138{
139 struct reg inferior_registers;
47221191
RE
140 int ret;
141 int regno;
142
9ac8a7c2 143 ret = ptrace (PT_GETREGS, ptid_get_pid (regcache_get_ptid (regcache)),
9f8e0089 144 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
47221191
RE
145
146 if (ret < 0)
147 {
edefbb7c 148 warning (_("unable to fetch general registers"));
47221191
RE
149 return;
150 }
151
56be3814 152 arm_supply_gregset (regcache, &inferior_registers);
47221191
RE
153}
154
155static void
56be3814 156fetch_fp_register (struct regcache *regcache, int regno)
47221191
RE
157{
158 struct fpreg inferior_fp_registers;
159 int ret;
160
9ac8a7c2 161 ret = ptrace (PT_GETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)),
9f8e0089 162 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
47221191
RE
163
164 if (ret < 0)
165 {
edefbb7c 166 warning (_("unable to fetch floating-point register"));
47221191
RE
167 return;
168 }
169
170 switch (regno)
171 {
172 case ARM_FPS_REGNUM:
56be3814 173 regcache_raw_supply (regcache, ARM_FPS_REGNUM,
23a6d369 174 (char *) &inferior_fp_registers.fpr_fpsr);
47221191
RE
175 break;
176
177 default:
56be3814 178 regcache_raw_supply (regcache, regno,
23a6d369 179 (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
47221191
RE
180 break;
181 }
182}
183
184static void
56be3814 185fetch_fp_regs (struct regcache *regcache)
47221191
RE
186{
187 struct fpreg inferior_fp_registers;
188 int ret;
189 int regno;
190
9ac8a7c2 191 ret = ptrace (PT_GETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)),
9f8e0089 192 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
47221191
RE
193
194 if (ret < 0)
195 {
edefbb7c 196 warning (_("unable to fetch general registers"));
47221191
RE
197 return;
198 }
199
56be3814 200 arm_supply_fparegset (regcache, &inferior_fp_registers);
e7a42bc8
FN
201}
202
f6ac5f3d
PA
203void
204arm_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
47221191
RE
205{
206 if (regno >= 0)
207 {
208 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
56be3814 209 fetch_register (regcache, regno);
47221191 210 else
56be3814 211 fetch_fp_register (regcache, regno);
47221191
RE
212 }
213 else
214 {
56be3814
UW
215 fetch_regs (regcache);
216 fetch_fp_regs (regcache);
47221191
RE
217 }
218}
219
220
221static void
56be3814 222store_register (const struct regcache *regcache, int regno)
e7a42bc8 223{
ac7936df 224 struct gdbarch *gdbarch = regcache->arch ();
e7a42bc8 225 struct reg inferior_registers;
47221191
RE
226 int ret;
227
9ac8a7c2 228 ret = ptrace (PT_GETREGS, ptid_get_pid (regcache_get_ptid (regcache)),
9f8e0089 229 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
47221191
RE
230
231 if (ret < 0)
232 {
edefbb7c 233 warning (_("unable to fetch general registers"));
47221191
RE
234 return;
235 }
236
237 switch (regno)
238 {
239 case ARM_SP_REGNUM:
56be3814 240 regcache_raw_collect (regcache, ARM_SP_REGNUM,
822c9732 241 (char *) &inferior_registers.r_sp);
47221191
RE
242 break;
243
244 case ARM_LR_REGNUM:
56be3814 245 regcache_raw_collect (regcache, ARM_LR_REGNUM,
822c9732 246 (char *) &inferior_registers.r_lr);
47221191 247 break;
e7a42bc8 248
47221191
RE
249 case ARM_PC_REGNUM:
250 if (arm_apcs_32)
56be3814 251 regcache_raw_collect (regcache, ARM_PC_REGNUM,
822c9732 252 (char *) &inferior_registers.r_pc);
47221191
RE
253 else
254 {
255 unsigned pc_val;
e7a42bc8 256
56be3814 257 regcache_raw_collect (regcache, ARM_PC_REGNUM,
822c9732 258 (char *) &pc_val);
47221191 259
b2cb219a 260 pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
bf6ae464 261 inferior_registers.r_pc ^= gdbarch_addr_bits_remove
b2cb219a 262 (gdbarch, inferior_registers.r_pc);
47221191
RE
263 inferior_registers.r_pc |= pc_val;
264 }
265 break;
266
267 case ARM_PS_REGNUM:
268 if (arm_apcs_32)
56be3814 269 regcache_raw_collect (regcache, ARM_PS_REGNUM,
822c9732 270 (char *) &inferior_registers.r_cpsr);
47221191
RE
271 else
272 {
273 unsigned psr_val;
274
56be3814 275 regcache_raw_collect (regcache, ARM_PS_REGNUM,
822c9732 276 (char *) &psr_val);
47221191 277
b2cb219a 278 psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
bf6ae464 279 inferior_registers.r_pc = gdbarch_addr_bits_remove
b2cb219a 280 (gdbarch, inferior_registers.r_pc);
47221191
RE
281 inferior_registers.r_pc |= psr_val;
282 }
283 break;
284
285 default:
56be3814 286 regcache_raw_collect (regcache, regno,
822c9732 287 (char *) &inferior_registers.r[regno]);
47221191
RE
288 break;
289 }
290
9ac8a7c2 291 ret = ptrace (PT_SETREGS, ptid_get_pid (regcache_get_ptid (regcache)),
9f8e0089 292 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
47221191
RE
293
294 if (ret < 0)
edefbb7c 295 warning (_("unable to write register %d to inferior"), regno);
47221191
RE
296}
297
298static void
56be3814 299store_regs (const struct regcache *regcache)
47221191 300{
ac7936df 301 struct gdbarch *gdbarch = regcache->arch ();
47221191
RE
302 struct reg inferior_registers;
303 int ret;
304 int regno;
305
306
307 for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
56be3814 308 regcache_raw_collect (regcache, regno,
822c9732 309 (char *) &inferior_registers.r[regno]);
47221191 310
56be3814 311 regcache_raw_collect (regcache, ARM_SP_REGNUM,
822c9732 312 (char *) &inferior_registers.r_sp);
56be3814 313 regcache_raw_collect (regcache, ARM_LR_REGNUM,
822c9732 314 (char *) &inferior_registers.r_lr);
47221191
RE
315
316 if (arm_apcs_32)
317 {
56be3814 318 regcache_raw_collect (regcache, ARM_PC_REGNUM,
822c9732 319 (char *) &inferior_registers.r_pc);
56be3814 320 regcache_raw_collect (regcache, ARM_PS_REGNUM,
822c9732 321 (char *) &inferior_registers.r_cpsr);
47221191
RE
322 }
323 else
324 {
325 unsigned pc_val;
326 unsigned psr_val;
327
56be3814 328 regcache_raw_collect (regcache, ARM_PC_REGNUM,
822c9732 329 (char *) &pc_val);
56be3814 330 regcache_raw_collect (regcache, ARM_PS_REGNUM,
822c9732 331 (char *) &psr_val);
47221191 332
b2cb219a
UW
333 pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
334 psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
47221191
RE
335
336 inferior_registers.r_pc = pc_val | psr_val;
337 }
338
9ac8a7c2 339 ret = ptrace (PT_SETREGS, ptid_get_pid (regcache_get_ptid (regcache)),
9f8e0089 340 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
47221191
RE
341
342 if (ret < 0)
edefbb7c 343 warning (_("unable to store general registers"));
47221191
RE
344}
345
346static void
56be3814 347store_fp_register (const struct regcache *regcache, int regno)
47221191
RE
348{
349 struct fpreg inferior_fp_registers;
350 int ret;
351
9ac8a7c2 352 ret = ptrace (PT_GETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)),
9f8e0089 353 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
47221191
RE
354
355 if (ret < 0)
356 {
edefbb7c 357 warning (_("unable to fetch floating-point registers"));
47221191
RE
358 return;
359 }
360
361 switch (regno)
362 {
363 case ARM_FPS_REGNUM:
56be3814 364 regcache_raw_collect (regcache, ARM_FPS_REGNUM,
822c9732 365 (char *) &inferior_fp_registers.fpr_fpsr);
47221191
RE
366 break;
367
368 default:
56be3814 369 regcache_raw_collect (regcache, regno,
822c9732 370 (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
47221191
RE
371 break;
372 }
373
9ac8a7c2 374 ret = ptrace (PT_SETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)),
9f8e0089 375 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
47221191
RE
376
377 if (ret < 0)
edefbb7c 378 warning (_("unable to write register %d to inferior"), regno);
47221191
RE
379}
380
381static void
56be3814 382store_fp_regs (const struct regcache *regcache)
47221191
RE
383{
384 struct fpreg inferior_fp_registers;
385 int ret;
386 int regno;
387
388
389 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
56be3814 390 regcache_raw_collect (regcache, regno,
822c9732 391 (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
47221191 392
56be3814 393 regcache_raw_collect (regcache, ARM_FPS_REGNUM,
822c9732 394 (char *) &inferior_fp_registers.fpr_fpsr);
47221191 395
9ac8a7c2 396 ret = ptrace (PT_SETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)),
9f8e0089 397 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
47221191
RE
398
399 if (ret < 0)
edefbb7c 400 warning (_("unable to store floating-point registers"));
47221191
RE
401}
402
f6ac5f3d
PA
403void
404arm_nbsd_nat_target::store_registers (struct regcache *regcache, int regno)
47221191
RE
405{
406 if (regno >= 0)
407 {
408 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
56be3814 409 store_register (regcache, regno);
47221191 410 else
56be3814 411 store_fp_register (regcache, regno);
47221191
RE
412 }
413 else
414 {
56be3814
UW
415 store_regs (regcache);
416 store_fp_regs (regcache);
47221191 417 }
e7a42bc8
FN
418}
419
b34db576 420static void
9eefc95f
UW
421fetch_elfcore_registers (struct regcache *regcache,
422 char *core_reg_sect, unsigned core_reg_size,
b34db576
RE
423 int which, CORE_ADDR ignore)
424{
425 struct reg gregset;
426 struct fpreg fparegset;
e7a42bc8 427
b34db576
RE
428 switch (which)
429 {
430 case 0: /* Integer registers. */
431 if (core_reg_size != sizeof (struct reg))
edefbb7c 432 warning (_("wrong size of register set in core file"));
b34db576
RE
433 else
434 {
435 /* The memcpy may be unnecessary, but we can't really be sure
436 of the alignment of the data in the core file. */
437 memcpy (&gregset, core_reg_sect, sizeof (gregset));
9eefc95f 438 arm_supply_gregset (regcache, &gregset);
b34db576
RE
439 }
440 break;
441
442 case 2:
443 if (core_reg_size != sizeof (struct fpreg))
edefbb7c 444 warning (_("wrong size of FPA register set in core file"));
b34db576
RE
445 else
446 {
447 /* The memcpy may be unnecessary, but we can't really be sure
448 of the alignment of the data in the core file. */
449 memcpy (&fparegset, core_reg_sect, sizeof (fparegset));
9eefc95f 450 arm_supply_fparegset (regcache, &fparegset);
b34db576
RE
451 }
452 break;
3e56fc4b 453
b34db576
RE
454 default:
455 /* Don't know what kind of register request this is; just ignore it. */
456 break;
457 }
e7a42bc8
FN
458}
459
b34db576
RE
460static struct core_fns arm_netbsd_elfcore_fns =
461{
462 bfd_target_elf_flavour, /* core_flovour. */
463 default_check_format, /* check_format. */
464 default_core_sniffer, /* core_sniffer. */
465 fetch_elfcore_registers, /* core_read_registers. */
466 NULL
467};
468
3e56fc4b
RE
469void
470_initialize_arm_netbsd_nat (void)
471{
d9f719f1 472 add_inf_child_target (&the_arm_netbsd_nat_target);
2b73aeb1 473
00e32a35 474 deprecated_add_core_fns (&arm_netbsd_elfcore_fns);
3e56fc4b 475}
This page took 1.054477 seconds and 4 git commands to generate.