[ARM] Update knowledge of bfd architectures
[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, regcache->ptid ().pid (),
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, regcache->ptid ().pid (),
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, regcache->ptid ().pid (),
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, regcache->ptid ().pid (),
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, regcache->ptid ().pid (),
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 (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
232       break;
233
234     case ARM_LR_REGNUM:
235       regcache->raw_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
236       break;
237
238     case ARM_PC_REGNUM:
239       if (arm_apcs_32)
240         regcache->raw_collect (ARM_PC_REGNUM,
241                                (char *) &inferior_registers.r_pc);
242       else
243         {
244           unsigned pc_val;
245
246           regcache->raw_collect (ARM_PC_REGNUM, (char *) &pc_val);
247           
248           pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
249           inferior_registers.r_pc ^= gdbarch_addr_bits_remove
250                                        (gdbarch, inferior_registers.r_pc);
251           inferior_registers.r_pc |= pc_val;
252         }
253       break;
254
255     case ARM_PS_REGNUM:
256       if (arm_apcs_32)
257         regcache->raw_collect (ARM_PS_REGNUM,
258                                (char *) &inferior_registers.r_cpsr);
259       else
260         {
261           unsigned psr_val;
262
263           regcache->raw_collect (ARM_PS_REGNUM, (char *) &psr_val);
264
265           psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
266           inferior_registers.r_pc = gdbarch_addr_bits_remove
267                                       (gdbarch, inferior_registers.r_pc);
268           inferior_registers.r_pc |= psr_val;
269         }
270       break;
271
272     default:
273       regcache->raw_collect (regno, (char *) &inferior_registers.r[regno]);
274       break;
275     }
276
277   ret = ptrace (PT_SETREGS, regcache->ptid ().pid (),
278                 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
279
280   if (ret < 0)
281     warning (_("unable to write register %d to inferior"), regno);
282 }
283
284 static void
285 store_regs (const struct regcache *regcache)
286 {
287   struct gdbarch *gdbarch = regcache->arch ();
288   struct reg inferior_registers;
289   int ret;
290   int regno;
291
292
293   for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
294     regcache->raw_collect (regno, (char *) &inferior_registers.r[regno]);
295
296   regcache->raw_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
297   regcache->raw_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
298
299   if (arm_apcs_32)
300     {
301       regcache->raw_collect (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
302       regcache->raw_collect (ARM_PS_REGNUM,
303                              (char *) &inferior_registers.r_cpsr);
304     }
305   else
306     {
307       unsigned pc_val;
308       unsigned psr_val;
309
310       regcache->raw_collect (ARM_PC_REGNUM, (char *) &pc_val);
311       regcache->raw_collect (ARM_PS_REGNUM, (char *) &psr_val);
312           
313       pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
314       psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
315
316       inferior_registers.r_pc = pc_val | psr_val;
317     }
318
319   ret = ptrace (PT_SETREGS, regcache->ptid ().pid (),
320                 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
321
322   if (ret < 0)
323     warning (_("unable to store general registers"));
324 }
325
326 static void
327 store_fp_register (const struct regcache *regcache, int regno)
328 {
329   struct fpreg inferior_fp_registers;
330   int ret;
331
332   ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
333                 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
334
335   if (ret < 0)
336     {
337       warning (_("unable to fetch floating-point registers"));
338       return;
339     }
340
341   switch (regno)
342     {
343     case ARM_FPS_REGNUM:
344       regcache->raw_collect (ARM_FPS_REGNUM,
345                              (char *) &inferior_fp_registers.fpr_fpsr);
346       break;
347
348     default:
349       regcache->raw_collect
350         (regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
351       break;
352     }
353
354   ret = ptrace (PT_SETFPREGS, regcache->ptid ().pid (),
355                 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
356
357   if (ret < 0)
358     warning (_("unable to write register %d to inferior"), regno);
359 }
360
361 static void
362 store_fp_regs (const struct regcache *regcache)
363 {
364   struct fpreg inferior_fp_registers;
365   int ret;
366   int regno;
367
368
369   for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
370     regcache->raw_collect
371       (regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
372
373   regcache->raw_collect (ARM_FPS_REGNUM,
374                          (char *) &inferior_fp_registers.fpr_fpsr);
375
376   ret = ptrace (PT_SETFPREGS, regcache->ptid ().pid (),
377                 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
378
379   if (ret < 0)
380     warning (_("unable to store floating-point registers"));
381 }
382
383 void
384 arm_nbsd_nat_target::store_registers (struct regcache *regcache, int regno)
385 {
386   if (regno >= 0)
387     {
388       if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
389         store_register (regcache, regno);
390       else
391         store_fp_register (regcache, regno);
392     }
393   else
394     {
395       store_regs (regcache);
396       store_fp_regs (regcache);
397     }
398 }
399
400 static void
401 fetch_elfcore_registers (struct regcache *regcache,
402                          char *core_reg_sect, unsigned core_reg_size,
403                          int which, CORE_ADDR ignore)
404 {
405   struct reg gregset;
406   struct fpreg fparegset;
407
408   switch (which)
409     {
410     case 0:     /* Integer registers.  */
411       if (core_reg_size != sizeof (struct reg))
412         warning (_("wrong size of register set in core file"));
413       else
414         {
415           /* The memcpy may be unnecessary, but we can't really be sure
416              of the alignment of the data in the core file.  */
417           memcpy (&gregset, core_reg_sect, sizeof (gregset));
418           arm_supply_gregset (regcache, &gregset);
419         }
420       break;
421
422     case 2:
423       if (core_reg_size != sizeof (struct fpreg))
424         warning (_("wrong size of FPA register set in core file"));
425       else
426         {
427           /* The memcpy may be unnecessary, but we can't really be sure
428              of the alignment of the data in the core file.  */
429           memcpy (&fparegset, core_reg_sect, sizeof (fparegset));
430           arm_supply_fparegset (regcache, &fparegset);
431         }
432       break;
433
434     default:
435       /* Don't know what kind of register request this is; just ignore it.  */
436       break;
437     }
438 }
439
440 static struct core_fns arm_netbsd_elfcore_fns =
441 {
442   bfd_target_elf_flavour,               /* core_flovour.  */
443   default_check_format,                 /* check_format.  */
444   default_core_sniffer,                 /* core_sniffer.  */
445   fetch_elfcore_registers,              /* core_read_registers.  */
446   NULL
447 };
448
449 void
450 _initialize_arm_netbsd_nat (void)
451 {
452   add_inf_child_target (&the_arm_netbsd_nat_target);
453
454   deprecated_add_core_fns (&arm_netbsd_elfcore_fns);
455 }