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