GDB (xrefs)
/tmp/gdb-7.10/gdb/ppcnbsd-nat.c
Go to the documentation of this file.
1 /* Native-dependent code for NetBSD/powerpc.
2 
3  Copyright (C) 2002-2015 Free Software Foundation, Inc.
4 
5  Contributed by Wasabi Systems, Inc.
6 
7  This file is part of GDB.
8 
9  This program is free software; you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 3 of the License, or
12  (at your option) any later version.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 
22 #include "defs.h"
23 
24 #include <sys/types.h>
25 #include <sys/ptrace.h>
26 #include <machine/reg.h>
27 #include <machine/frame.h>
28 #include <machine/pcb.h>
29 
30 #include "gdbcore.h"
31 #include "inferior.h"
32 #include "regcache.h"
33 
34 #include "ppc-tdep.h"
35 #include "ppcnbsd-tdep.h"
36 #include "bsd-kvm.h"
37 #include "inf-ptrace.h"
38 
39 /* Returns true if PT_GETREGS fetches this register. */
40 
41 static int
43 {
44  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
45 
46  return ((regnum >= tdep->ppc_gp0_regnum
47  && regnum < tdep->ppc_gp0_regnum + ppc_num_gprs)
48  || regnum == tdep->ppc_lr_regnum
49  || regnum == tdep->ppc_cr_regnum
50  || regnum == tdep->ppc_xer_regnum
51  || regnum == tdep->ppc_ctr_regnum
52  || regnum == gdbarch_pc_regnum (gdbarch));
53 }
54 
55 /* Like above, but for PT_GETFPREGS. */
56 
57 static int
59 {
60  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
61 
62  /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
63  point registers. Traditionally, GDB's register set has still
64  listed the floating point registers for such machines, so this
65  code is harmless. However, the new E500 port actually omits the
66  floating point registers entirely from the register set --- they
67  don't even have register numbers assigned to them.
68 
69  It's not clear to me how best to update this code, so this assert
70  will alert the first person to encounter the NetBSD/E500
71  combination to the problem. */
73 
74  return ((regnum >= tdep->ppc_fp0_regnum
75  && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs)
76  || regnum == tdep->ppc_fpscr_regnum);
77 }
78 
79 static void
81  struct regcache *regcache, int regnum)
82 {
83  struct gdbarch *gdbarch = get_regcache_arch (regcache);
84 
85  if (regnum == -1 || getregs_supplies (gdbarch, regnum))
86  {
87  struct reg regs;
88 
89  if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
90  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
91  perror_with_name (_("Couldn't get registers"));
92 
94  regnum, &regs, sizeof regs);
95  }
96 
97  if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
98  {
99  struct fpreg fpregs;
100 
101  if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
102  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
103  perror_with_name (_("Couldn't get FP registers"));
104 
106  regnum, &fpregs, sizeof fpregs);
107  }
108 }
109 
110 static void
112  struct regcache *regcache, int regnum)
113 {
114  struct gdbarch *gdbarch = get_regcache_arch (regcache);
115 
116  if (regnum == -1 || getregs_supplies (gdbarch, regnum))
117  {
118  struct reg regs;
119 
120  if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
121  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
122  perror_with_name (_("Couldn't get registers"));
123 
125  regnum, &regs, sizeof regs);
126 
127  if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
128  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
129  perror_with_name (_("Couldn't write registers"));
130  }
131 
132  if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
133  {
134  struct fpreg fpregs;
135 
136  if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
137  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
138  perror_with_name (_("Couldn't get FP registers"));
139 
141  regnum, &fpregs, sizeof fpregs);
142 
143  if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
144  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
145  perror_with_name (_("Couldn't set FP registers"));
146  }
147 }
148 
149 static int
150 ppcnbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
151 {
152  struct switchframe sf;
153  struct callframe cf;
154  struct gdbarch *gdbarch = get_regcache_arch (regcache);
155  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
156  int i;
157 
158  /* The stack pointer shouldn't be zero. */
159  if (pcb->pcb_sp == 0)
160  return 0;
161 
162  read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf);
163  regcache_raw_supply (regcache, tdep->ppc_cr_regnum, &sf.cr);
164  regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 2, &sf.fixreg2);
165  for (i = 0 ; i < 19 ; i++)
166  regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 13 + i,
167  &sf.fixreg[i]);
168 
169  read_memory(sf.sp, (gdb_byte *)&cf, sizeof(cf));
170  regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 30, &cf.r30);
171  regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 31, &cf.r31);
172  regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 1, &cf.sp);
173 
174  read_memory(cf.sp, (gdb_byte *)&cf, sizeof(cf));
175  regcache_raw_supply (regcache, tdep->ppc_lr_regnum, &cf.lr);
176  regcache_raw_supply (regcache, gdbarch_pc_regnum (gdbarch), &cf.lr);
177 
178  return 1;
179 }
180 
181 /* Provide a prototype to silence -Wmissing-prototypes. */
182 void _initialize_ppcnbsd_nat (void);
183 
184 void
186 {
187  struct target_ops *t;
188 
189  /* Support debugging kernel virtual memory images. */
191 
192  /* Add in local overrides. */
193  t = inf_ptrace_target ();
196  add_target (t);
197 }
void add_target(struct target_ops *t)
Definition: target.c:395
int ppc_lr_regnum
Definition: ppc-tdep.h:218
struct gdbarch * get_regcache_arch(const struct regcache *regcache)
Definition: regcache.c:297
void ppc_supply_fpregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *fpregs, size_t len)
Definition: rs6000-tdep.c:550
int ppc_fpscr_regnum
Definition: ppc-tdep.h:228
#define _(String)
Definition: gdb_locale.h:40
struct target_ops * inf_ptrace_target(void)
Definition: inf-ptrace.c:668
int ppc_cr_regnum
Definition: ppc-tdep.h:217
struct gdbarch_tdep * gdbarch_tdep(struct gdbarch *gdbarch)
Definition: gdbarch.c:1402
PTRACE_TYPE_RET ptrace()
void _initialize_ppcnbsd_nat(void)
Definition: ppcnbsd-nat.c:185
void ppc_collect_gregset(const struct regset *regset, const struct regcache *regcache, int regnum, void *gregs, size_t len)
Definition: rs6000-tdep.c:663
static int ppcnbsd_supply_pcb(struct regcache *regcache, struct pcb *pcb)
Definition: ppcnbsd-nat.c:150
int ppc_gp0_regnum
Definition: ppc-tdep.h:214
static int getfpregs_supplies(struct gdbarch *gdbarch, int regnum)
Definition: ppcnbsd-nat.c:58
static void ppcnbsd_store_inferior_registers(struct target_ops *ops, struct regcache *regcache, int regnum)
Definition: ppcnbsd-nat.c:111
static void ppcnbsd_fetch_inferior_registers(struct target_ops *ops, struct regcache *regcache, int regnum)
Definition: ppcnbsd-nat.c:80
#define gdb_assert(expr)
Definition: gdb_assert.h:33
void ppc_collect_fpregset(const struct regset *regset, const struct regcache *regcache, int regnum, void *fpregs, size_t len)
Definition: rs6000-tdep.c:710
int regnum
Definition: aarch64-tdep.c:69
void read_memory(CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
Definition: corefile.c:244
Definition: regdef.h:22
int ptid_get_pid(ptid_t ptid)
Definition: ptid.c:52
bfd_byte gdb_byte
Definition: common-types.h:38
int ppc_ctr_regnum
Definition: ppc-tdep.h:219
void(* to_fetch_registers)(struct target_ops *, struct regcache *, int) TARGET_DEFAULT_IGNORE()
Definition: target.h:472
void void void void void void void void void perror_with_name(const char *string) ATTRIBUTE_NORETURN
Definition: utils.c:979
ptid_t inferior_ptid
Definition: infcmd.c:124
int ppc_xer_regnum
Definition: ppc-tdep.h:220
const struct regset ppcnbsd_fpregset
Definition: ppcnbsd-tdep.c:48
void regcache_raw_supply(struct regcache *regcache, int regnum, const void *buf)
Definition: regcache.c:1041
int gdbarch_pc_regnum(struct gdbarch *gdbarch)
Definition: gdbarch.c:1998
static int getregs_supplies(struct gdbarch *gdbarch, int regnum)
Definition: ppcnbsd-nat.c:42
#define PTRACE_TYPE_ARG3
Definition: config.h:658
void bsd_kvm_add_target(int(*supply_pcb)(struct regcache *, struct pcb *))
Definition: bsd-kvm.c:351
const struct regset ppcnbsd_gregset
Definition: ppcnbsd-tdep.c:42
void(* to_store_registers)(struct target_ops *, struct regcache *, int) TARGET_DEFAULT_NORETURN(noprocess())
Definition: target.h:474
int ppc_floating_point_unit_p(struct gdbarch *gdbarch)
Definition: rs6000-tdep.c:212
int ppc_fp0_regnum
Definition: ppc-tdep.h:227
void ppc_supply_gregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *gregs, size_t len)
Definition: rs6000-tdep.c:505