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