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