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