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