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