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