GDB (xrefs)
/tmp/gdb-7.10/gdb/armnbsd-nat.c
Go to the documentation of this file.
1 /* Native-dependent code for BSD Unix running on ARM's, for GDB.
2 
3  Copyright (C) 1988-2015 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 extern int arm_apcs_32;
34 
35 static void
36 arm_supply_gregset (struct regcache *regcache, struct reg *gregset)
37 {
38  int regno;
39  CORE_ADDR r_pc;
40 
41  /* Integer registers. */
42  for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
43  regcache_raw_supply (regcache, regno, (char *) &gregset->r[regno]);
44 
45  regcache_raw_supply (regcache, ARM_SP_REGNUM,
46  (char *) &gregset->r_sp);
48  (char *) &gregset->r_lr);
49  /* This is ok: we're running native... */
50  r_pc = gdbarch_addr_bits_remove (get_regcache_arch (regcache), gregset->r_pc);
51  regcache_raw_supply (regcache, ARM_PC_REGNUM, (char *) &r_pc);
52 
53  if (arm_apcs_32)
55  (char *) &gregset->r_cpsr);
56  else
58  (char *) &gregset->r_pc);
59 }
60 
61 static void
62 arm_supply_fparegset (struct regcache *regcache, struct fpreg *fparegset)
63 {
64  int regno;
65 
66  for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
67  regcache_raw_supply (regcache, regno,
68  (char *) &fparegset->fpr[regno - ARM_F0_REGNUM]);
69 
71  (char *) &fparegset->fpr_fpsr);
72 }
73 
74 static void
75 fetch_register (struct regcache *regcache, int regno)
76 {
77  struct reg inferior_registers;
78  int ret;
79 
80  ret = ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
81  (PTRACE_TYPE_ARG3) &inferior_registers, 0);
82 
83  if (ret < 0)
84  {
85  warning (_("unable to fetch general register"));
86  return;
87  }
88 
89  switch (regno)
90  {
91  case ARM_SP_REGNUM:
93  (char *) &inferior_registers.r_sp);
94  break;
95 
96  case ARM_LR_REGNUM:
98  (char *) &inferior_registers.r_lr);
99  break;
100 
101  case ARM_PC_REGNUM:
102  /* This is ok: we're running native... */
103  inferior_registers.r_pc = gdbarch_addr_bits_remove
104  (get_regcache_arch (regcache),
105  inferior_registers.r_pc);
107  (char *) &inferior_registers.r_pc);
108  break;
109 
110  case ARM_PS_REGNUM:
111  if (arm_apcs_32)
113  (char *) &inferior_registers.r_cpsr);
114  else
116  (char *) &inferior_registers.r_pc);
117  break;
118 
119  default:
120  regcache_raw_supply (regcache, regno,
121  (char *) &inferior_registers.r[regno]);
122  break;
123  }
124 }
125 
126 static void
128 {
129  struct reg inferior_registers;
130  int ret;
131  int regno;
132 
133  ret = ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
134  (PTRACE_TYPE_ARG3) &inferior_registers, 0);
135 
136  if (ret < 0)
137  {
138  warning (_("unable to fetch general registers"));
139  return;
140  }
141 
142  arm_supply_gregset (regcache, &inferior_registers);
143 }
144 
145 static void
146 fetch_fp_register (struct regcache *regcache, int regno)
147 {
148  struct fpreg inferior_fp_registers;
149  int ret;
150 
151  ret = ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
152  (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
153 
154  if (ret < 0)
155  {
156  warning (_("unable to fetch floating-point register"));
157  return;
158  }
159 
160  switch (regno)
161  {
162  case ARM_FPS_REGNUM:
164  (char *) &inferior_fp_registers.fpr_fpsr);
165  break;
166 
167  default:
168  regcache_raw_supply (regcache, regno,
169  (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
170  break;
171  }
172 }
173 
174 static void
176 {
177  struct fpreg inferior_fp_registers;
178  int ret;
179  int regno;
180 
181  ret = ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
182  (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
183 
184  if (ret < 0)
185  {
186  warning (_("unable to fetch general registers"));
187  return;
188  }
189 
190  arm_supply_fparegset (regcache, &inferior_fp_registers);
191 }
192 
193 static void
195  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 = get_regcache_arch (regcache);
216  struct reg inferior_registers;
217  int ret;
218 
219  ret = ptrace (PT_GETREGS, ptid_get_pid (inferior_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:
232  (char *) &inferior_registers.r_sp);
233  break;
234 
235  case ARM_LR_REGNUM:
237  (char *) &inferior_registers.r_lr);
238  break;
239 
240  case ARM_PC_REGNUM:
241  if (arm_apcs_32)
243  (char *) &inferior_registers.r_pc);
244  else
245  {
246  unsigned pc_val;
247 
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)
261  (char *) &inferior_registers.r_cpsr);
262  else
263  {
264  unsigned psr_val;
265 
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 (inferior_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 = get_regcache_arch (regcache);
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);
305  (char *) &inferior_registers.r_lr);
306 
307  if (arm_apcs_32)
308  {
310  (char *) &inferior_registers.r_pc);
312  (char *) &inferior_registers.r_cpsr);
313  }
314  else
315  {
316  unsigned pc_val;
317  unsigned psr_val;
318 
320  (char *) &pc_val);
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 (inferior_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 (inferior_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:
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 (inferior_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
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 
385  (char *) &inferior_fp_registers.fpr_fpsr);
386 
387  ret = ptrace (PT_SETFPREGS, ptid_get_pid (inferior_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 static void
396  struct regcache *regcache, int regno)
397 {
398  if (regno >= 0)
399  {
400  if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
401  store_register (regcache, regno);
402  else
403  store_fp_register (regcache, regno);
404  }
405  else
406  {
407  store_regs (regcache);
408  store_fp_regs (regcache);
409  }
410 }
411 
412 struct md_core
413 {
414  struct reg intreg;
415  struct fpreg freg;
416 };
417 
418 static void
420  char *core_reg_sect, unsigned core_reg_size,
421  int which, CORE_ADDR ignore)
422 {
423  struct md_core *core_reg = (struct md_core *) core_reg_sect;
424  int regno;
425  CORE_ADDR r_pc;
426 
427  arm_supply_gregset (regcache, &core_reg->intreg);
428  arm_supply_fparegset (regcache, &core_reg->freg);
429 }
430 
431 static void
433  char *core_reg_sect, unsigned core_reg_size,
434  int which, CORE_ADDR ignore)
435 {
436  struct reg gregset;
437  struct fpreg fparegset;
438 
439  switch (which)
440  {
441  case 0: /* Integer registers. */
442  if (core_reg_size != sizeof (struct reg))
443  warning (_("wrong size of register set in core file"));
444  else
445  {
446  /* The memcpy may be unnecessary, but we can't really be sure
447  of the alignment of the data in the core file. */
448  memcpy (&gregset, core_reg_sect, sizeof (gregset));
449  arm_supply_gregset (regcache, &gregset);
450  }
451  break;
452 
453  case 2:
454  if (core_reg_size != sizeof (struct fpreg))
455  warning (_("wrong size of FPA register set in core file"));
456  else
457  {
458  /* The memcpy may be unnecessary, but we can't really be sure
459  of the alignment of the data in the core file. */
460  memcpy (&fparegset, core_reg_sect, sizeof (fparegset));
461  arm_supply_fparegset (regcache, &fparegset);
462  }
463  break;
464 
465  default:
466  /* Don't know what kind of register request this is; just ignore it. */
467  break;
468  }
469 }
470 
471 static struct core_fns arm_netbsd_core_fns =
472 {
473  bfd_target_unknown_flavour, /* core_flovour. */
474  default_check_format, /* check_format. */
475  default_core_sniffer, /* core_sniffer. */
476  fetch_core_registers, /* core_read_registers. */
477  NULL
478 };
479 
480 static struct core_fns arm_netbsd_elfcore_fns =
481 {
482  bfd_target_elf_flavour, /* core_flovour. */
483  default_check_format, /* check_format. */
484  default_core_sniffer, /* core_sniffer. */
485  fetch_elfcore_registers, /* core_read_registers. */
486  NULL
487 };
488 
489 void
491 {
492  struct target_ops *t;
493 
494  t = inf_ptrace_target ();
497  add_target (t);
498 
499  deprecated_add_core_fns (&arm_netbsd_core_fns);
500  deprecated_add_core_fns (&arm_netbsd_elfcore_fns);
501 }
void add_target(struct target_ops *t)
Definition: target.c:395
int default_check_format(bfd *abfd)
Definition: corelow.c:164
static void fetch_core_registers(struct regcache *regcache, char *core_reg_sect, unsigned core_reg_size, int which, CORE_ADDR ignore)
Definition: armnbsd-nat.c:419
bfd_vma CORE_ADDR
Definition: common-types.h:41
struct gdbarch * get_regcache_arch(const struct regcache *regcache)
Definition: regcache.c:297
void warning(const char *fmt,...)
Definition: errors.c:26
int arm_apcs_32
Definition: arm-tdep.c:278
static void fetch_register(struct regcache *regcache, int regno)
Definition: armnbsd-nat.c:75
#define _(String)
Definition: gdb_locale.h:40
struct target_ops * inf_ptrace_target(void)
Definition: inf-ptrace.c:668
static void armnbsd_store_registers(struct target_ops *ops, struct regcache *regcache, int regno)
Definition: armnbsd-nat.c:395
static void fetch_fp_register(struct regcache *regcache, int regno)
Definition: armnbsd-nat.c:146
PTRACE_TYPE_RET ptrace()
CORE_ADDR gdbarch_addr_bits_remove(struct gdbarch *gdbarch, CORE_ADDR addr)
Definition: gdbarch.c:2992
struct reg intreg
Definition: armnbsd-nat.c:414
static void store_fp_regs(const struct regcache *regcache)
Definition: armnbsd-nat.c:373
static void arm_supply_fparegset(struct regcache *regcache, struct fpreg *fparegset)
Definition: armnbsd-nat.c:62
void deprecated_add_core_fns(struct core_fns *cf)
Definition: corelow.c:104
static void fetch_fp_regs(struct regcache *regcache)
Definition: armnbsd-nat.c:175
Definition: regdef.h:22
int ptid_get_pid(ptid_t ptid)
Definition: ptid.c:52
static void arm_supply_gregset(struct regcache *regcache, struct reg *gregset)
Definition: armnbsd-nat.c:36
void(* to_fetch_registers)(struct target_ops *, struct regcache *, int) TARGET_DEFAULT_IGNORE()
Definition: target.h:472
static void armnbsd_fetch_registers(struct target_ops *ops, struct regcache *regcache, int regno)
Definition: armnbsd-nat.c:194
ptid_t inferior_ptid
Definition: infcmd.c:124
static void store_regs(const struct regcache *regcache)
Definition: armnbsd-nat.c:290
static void store_fp_register(const struct regcache *regcache, int regno)
Definition: armnbsd-nat.c:338
void _initialize_arm_netbsd_nat(void)
Definition: armnbsd-nat.c:490
struct fpreg freg
Definition: armnbsd-nat.c:415
void regcache_raw_supply(struct regcache *regcache, int regnum, const void *buf)
Definition: regcache.c:1041
static int ignore(struct target_ops *ops, struct gdbarch *gdbarch, struct bp_target_info *bp_tgt)
Definition: corelow.c:917
void regcache_raw_collect(const struct regcache *regcache, int regnum, void *buf)
Definition: regcache.c:1071
#define PTRACE_TYPE_ARG3
Definition: config.h:658
void(* to_store_registers)(struct target_ops *, struct regcache *, int) TARGET_DEFAULT_NORETURN(noprocess())
Definition: target.h:474
static void fetch_regs(struct regcache *regcache)
Definition: armnbsd-nat.c:127
int default_core_sniffer(struct core_fns *our_fns, bfd *abfd)
Definition: corelow.c:115
static void store_register(const struct regcache *regcache, int regno)
Definition: armnbsd-nat.c:213
static void fetch_elfcore_registers(struct regcache *regcache, char *core_reg_sect, unsigned core_reg_size, int which, CORE_ADDR ignore)
Definition: armnbsd-nat.c:432