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