GDB (xrefs)
/tmp/gdb-7.10/gdb/ppcobsd-nat.c
Go to the documentation of this file.
1 /* Native-dependent code for OpenBSD/powerpc.
2 
3  Copyright (C) 2004-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 
25 #include <sys/types.h>
26 #include <sys/ptrace.h>
27 #include <sys/signal.h>
28 #include <machine/frame.h>
29 #include <machine/pcb.h>
30 #include <machine/reg.h>
31 
32 #include "ppc-tdep.h"
33 #include "ppcobsd-tdep.h"
34 #include "inf-ptrace.h"
35 #include "obsd-nat.h"
36 #include "bsd-kvm.h"
37 
38 /* OpenBSD/powerpc didn't have PT_GETFPREGS/PT_SETFPREGS until release
39  4.0. On older releases the floating-point registers are handled by
40  PT_GETREGS/PT_SETREGS, but fpscr wasn't available.. */
41 
42 #ifdef PT_GETFPREGS
43 
44 /* Returns true if PT_GETFPREGS fetches this register. */
45 
46 static int
47 getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
48 {
49  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
50 
51  /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
52  point registers. Traditionally, GDB's register set has still
53  listed the floating point registers for such machines, so this
54  code is harmless. However, the new E500 port actually omits the
55  floating point registers entirely from the register set --- they
56  don't even have register numbers assigned to them.
57 
58  It's not clear to me how best to update this code, so this assert
59  will alert the first person to encounter the NetBSD/E500
60  combination to the problem. */
62 
63  return ((regnum >= tdep->ppc_fp0_regnum
64  && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs)
65  || regnum == tdep->ppc_fpscr_regnum);
66 }
67 
68 #endif /* PT_GETFPREGS */
69 
70 /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
71  for all registers. */
72 
73 static void
75  struct regcache *regcache, int regnum)
76 {
77  struct reg regs;
78 
79  if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
80  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
81  perror_with_name (_("Couldn't get registers"));
82 
83  ppc_supply_gregset (&ppcobsd_gregset, regcache, -1,
84  &regs, sizeof regs);
85 #ifndef PT_GETFPREGS
86  ppc_supply_fpregset (&ppcobsd_gregset, regcache, -1,
87  &regs, sizeof regs);
88 #endif
89 
90 #ifdef PT_GETFPREGS
91  if (regnum == -1
92  || getfpregs_supplies (get_regcache_arch (regcache), regnum))
93  {
94  struct fpreg fpregs;
95 
96  if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
97  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
98  perror_with_name (_("Couldn't get floating point status"));
99 
100  ppc_supply_fpregset (&ppcobsd_fpregset, regcache, -1,
101  &fpregs, sizeof fpregs);
102  }
103 #endif
104 }
105 
106 /* Store register REGNUM back into the inferior. If REGNUM is -1, do
107  this for all registers. */
108 
109 static void
111  struct regcache *regcache, int regnum)
112 {
113  struct reg regs;
114 
115  if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
116  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
117  perror_with_name (_("Couldn't get registers"));
118 
120  regnum, &regs, sizeof regs);
121 #ifndef PT_GETFPREGS
123  regnum, &regs, sizeof regs);
124 #endif
125 
126  if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
127  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
128  perror_with_name (_("Couldn't write registers"));
129 
130 #ifdef PT_GETFPREGS
131  if (regnum == -1
132  || getfpregs_supplies (get_regcache_arch (regcache), 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 floating point status"));
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 write floating point status"));
146  }
147 #endif
148 }
149 
150 
151 static int
152 ppcobsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
153 {
154  struct gdbarch *gdbarch = get_regcache_arch (regcache);
155  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
156  struct switchframe sf;
157  struct callframe cf;
158  int i, regnum;
159 
160  /* The following is true for OpenBSD 3.7:
161 
162  The pcb contains %r1 (the stack pointer) at the point of the
163  context switch in cpu_switch(). At that point we have a stack
164  frame as described by `struct switchframe', and below that a call
165  frame as described by `struct callframe'. From this information
166  we reconstruct the register state as it would look when we are in
167  cpu_switch(). */
168 
169  /* The stack pointer shouldn't be zero. */
170  if (pcb->pcb_sp == 0)
171  return 0;
172 
173  read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf);
174  regcache_raw_supply (regcache, gdbarch_sp_regnum (gdbarch), &sf.sp);
175  regcache_raw_supply (regcache, tdep->ppc_cr_regnum, &sf.cr);
176  regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 2, &sf.fixreg2);
177  for (i = 0, regnum = tdep->ppc_gp0_regnum + 13; i < 19; i++, regnum++)
178  regcache_raw_supply (regcache, regnum, &sf.fixreg[i]);
179 
180  read_memory (sf.sp, (gdb_byte *)&cf, sizeof cf);
181  regcache_raw_supply (regcache, gdbarch_pc_regnum (gdbarch), &cf.lr);
182  regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 30, &cf.r30);
183  regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 31, &cf.r31);
184 
185  return 1;
186 }
187 
188 
189 /* Provide a prototype to silence -Wmissing-prototypes. */
190 void _initialize_ppcobsd_nat (void);
191 
192 void
194 {
195  struct target_ops *t;
196 
197  /* Add in local overrides. */
198  t = inf_ptrace_target ();
201  obsd_add_target (t);
202 
203  /* General-purpose registers. */
204  ppcobsd_reg_offsets.r0_offset = offsetof (struct reg, gpr);
207  ppcobsd_reg_offsets.pc_offset = offsetof (struct reg, pc);
208  ppcobsd_reg_offsets.ps_offset = offsetof (struct reg, ps);
209  ppcobsd_reg_offsets.cr_offset = offsetof (struct reg, cnd);
210  ppcobsd_reg_offsets.lr_offset = offsetof (struct reg, lr);
211  ppcobsd_reg_offsets.ctr_offset = offsetof (struct reg, cnt);
212  ppcobsd_reg_offsets.xer_offset = offsetof (struct reg, xer);
213  ppcobsd_reg_offsets.mq_offset = offsetof (struct reg, mq);
214 
215  /* Floating-point registers. */
216  ppcobsd_reg_offsets.f0_offset = offsetof (struct reg, fpr);
218 #ifdef PT_GETFPREGS
219  ppcobsd_fpreg_offsets.f0_offset = offsetof (struct fpreg, fpr);
220  ppcobsd_fpreg_offsets.fpscr_offset = offsetof (struct fpreg, fpscr);
222 #endif
223 
224  /* AltiVec registers. */
225  ppcobsd_reg_offsets.vr0_offset = offsetof (struct vreg, vreg);
226  ppcobsd_reg_offsets.vscr_offset = offsetof (struct vreg, vscr);
227  ppcobsd_reg_offsets.vrsave_offset = offsetof (struct vreg, vrsave);
228 
229  /* Support debugging kernel virtual memory images. */
231 }
void obsd_add_target(struct target_ops *t)
Definition: obsd-nat.c:181
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
struct ppc_reg_offsets ppcobsd_reg_offsets
Definition: ppcobsd-tdep.c:36
#define _(String)
Definition: gdb_locale.h:40
struct target_ops * inf_ptrace_target(void)
Definition: inf-ptrace.c:668
static void ppcobsd_fetch_registers(struct target_ops *ops, struct regcache *regcache, int regnum)
Definition: ppcobsd-nat.c:74
int ppc_cr_regnum
Definition: ppc-tdep.h:217
struct gdbarch_tdep * gdbarch_tdep(struct gdbarch *gdbarch)
Definition: gdbarch.c:1402
static int ppcobsd_supply_pcb(struct regcache *regcache, struct pcb *pcb)
Definition: ppcobsd-nat.c:152
PTRACE_TYPE_RET ptrace()
void ppc_collect_gregset(const struct regset *regset, const struct regcache *regcache, int regnum, void *gregs, size_t len)
Definition: rs6000-tdep.c:663
const struct regset ppcobsd_fpregset
Definition: ppcobsd-tdep.c:77
int gdbarch_sp_regnum(struct gdbarch *gdbarch)
Definition: gdbarch.c:1981
void _initialize_ppcobsd_nat(void)
Definition: ppcobsd-nat.c:193
int ppc_gp0_regnum
Definition: ppc-tdep.h:214
struct ppc_reg_offsets ppcobsd_fpreg_offsets
Definition: ppcobsd-tdep.c:37
#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
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
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
#define PTRACE_TYPE_ARG3
Definition: config.h:658
const struct regset ppcobsd_gregset
Definition: ppcobsd-tdep.c:71
static int getfpregs_supplies(int regno)
Definition: m68klinux-nat.c:82
void bsd_kvm_add_target(int(*supply_pcb)(struct regcache *, struct pcb *))
Definition: bsd-kvm.c:351
static void ppcobsd_store_registers(struct target_ops *ops, struct regcache *regcache, int regnum)
Definition: ppcobsd-nat.c:110
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