Remove regcache_raw_supply
[external/binutils.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 }