Remove regcache_get_ptid
[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 (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->ptid ()),
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->ptid ()),
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->ptid ()),
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->ptid ()),
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->ptid ()),
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->ptid ()),
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->ptid ()),
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->ptid ()),
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->ptid ()),
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->ptid ()),
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_inf_child_target (&the_arm_netbsd_nat_target);
473
474   deprecated_add_core_fns (&arm_netbsd_elfcore_fns);
475 }