GDB (xrefs)
/tmp/gdb-8.1/gdb/ppc-obsd-nat.c
Go to the documentation of this file.
1 /* Native-dependent code for OpenBSD/powerpc.
2 
3  Copyright (C) 2004-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 
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 "ppc-obsd-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
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;
79 
80  if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
81  perror_with_name (_("Couldn't get registers"));
82 
84  &regs, sizeof regs);
85 #ifndef PT_GETFPREGS
87  &regs, sizeof regs);
88 #endif
89 
90 #ifdef PT_GETFPREGS
91  if (regnum == -1
93  {
94  struct fpreg fpregs;
95 
96  if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
97  perror_with_name (_("Couldn't get floating point status"));
98 
100  &fpregs, sizeof fpregs);
101  }
102 #endif
103 }
104 
105 /* Store register REGNUM back into the inferior. If REGNUM is -1, do
106  this for all registers. */
107 
108 static void
110  struct regcache *regcache, int regnum)
111 {
112  struct reg regs;
114 
115  if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
116  perror_with_name (_("Couldn't get registers"));
117 
119  regnum, &regs, sizeof regs);
120 #ifndef PT_GETFPREGS
122  regnum, &regs, sizeof regs);
123 #endif
124 
125  if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
126  perror_with_name (_("Couldn't write registers"));
127 
128 #ifdef PT_GETFPREGS
129  if (regnum == -1
131  {
132  struct fpreg fpregs;
133 
134  if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
135  perror_with_name (_("Couldn't get floating point status"));
136 
138  regnum, &fpregs, sizeof fpregs);
139 
140  if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
141  perror_with_name (_("Couldn't write floating point status"));
142  }
143 #endif
144 }
145 
146 
147 static int
148 ppcobsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
149 {
150  struct gdbarch *gdbarch = regcache->arch ();
151  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
152  struct switchframe sf;
153  struct callframe cf;
154  int i, regnum;
155 
156  /* The following is true for OpenBSD 3.7:
157 
158  The pcb contains %r1 (the stack pointer) at the point of the
159  context switch in cpu_switch(). At that point we have a stack
160  frame as described by `struct switchframe', and below that a call
161  frame as described by `struct callframe'. From this information
162  we reconstruct the register state as it would look when we are in
163  cpu_switch(). */
164 
165  /* The stack pointer shouldn't be zero. */
166  if (pcb->pcb_sp == 0)
167  return 0;
168 
169  read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf);
171  regcache_raw_supply (regcache, tdep->ppc_cr_regnum, &sf.cr);
172  regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 2, &sf.fixreg2);
173  for (i = 0, regnum = tdep->ppc_gp0_regnum + 13; i < 19; i++, regnum++)
174  regcache_raw_supply (regcache, regnum, &sf.fixreg[i]);
175 
176  read_memory (sf.sp, (gdb_byte *)&cf, sizeof cf);
178  regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 30, &cf.r30);
179  regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 31, &cf.r31);
180 
181  return 1;
182 }
183 
184 void
186 {
187  struct target_ops *t;
188 
189  /* Add in local overrides. */
190  t = inf_ptrace_target ();
193  obsd_add_target (t);
194 
195  /* General-purpose registers. */
196  ppcobsd_reg_offsets.r0_offset = offsetof (struct reg, gpr);
199  ppcobsd_reg_offsets.pc_offset = offsetof (struct reg, pc);
200  ppcobsd_reg_offsets.ps_offset = offsetof (struct reg, ps);
201  ppcobsd_reg_offsets.cr_offset = offsetof (struct reg, cnd);
202  ppcobsd_reg_offsets.lr_offset = offsetof (struct reg, lr);
203  ppcobsd_reg_offsets.ctr_offset = offsetof (struct reg, cnt);
204  ppcobsd_reg_offsets.xer_offset = offsetof (struct reg, xer);
205  ppcobsd_reg_offsets.mq_offset = offsetof (struct reg, mq);
206 
207  /* Floating-point registers. */
208  ppcobsd_reg_offsets.f0_offset = offsetof (struct reg, fpr);
210 #ifdef PT_GETFPREGS
211  ppcobsd_fpreg_offsets.f0_offset = offsetof (struct fpreg, fpr);
212  ppcobsd_fpreg_offsets.fpscr_offset = offsetof (struct fpreg, fpscr);
214 #endif
215 
216  /* AltiVec registers. */
217  ppcobsd_reg_offsets.vr0_offset = offsetof (struct vreg, vreg);
218  ppcobsd_reg_offsets.vscr_offset = offsetof (struct vreg, vscr);
219  ppcobsd_reg_offsets.vrsave_offset = offsetof (struct vreg, vrsave);
220 
221  /* Support debugging kernel virtual memory images. */
223 }
struct ppc_reg_offsets ppcobsd_fpreg_offsets
Definition: ppc-obsd-tdep.c:37
void obsd_add_target(struct target_ops *t)
Definition: obsd-nat.c:181
int ptid_get_pid(const ptid_t &ptid)
Definition: ptid.c:47
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t int int rusage_t pid_t pid
Definition: gnu-nat.c:1824
void ppc_supply_fpregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *fpregs, size_t len)
Definition: rs6000-tdep.c:561
const struct regset ppcobsd_gregset
Definition: ppc-obsd-tdep.c:71
int ppc_fpscr_regnum
Definition: ppc-tdep.h:241
ptid_t regcache_get_ptid(const struct regcache *regcache)
Definition: regcache.c:229
#define _(String)
Definition: gdb_locale.h:35
struct target_ops * inf_ptrace_target(void)
Definition: inf-ptrace.c:676
int ppc_cr_regnum
Definition: ppc-tdep.h:230
struct gdbarch_tdep * gdbarch_tdep(struct gdbarch *gdbarch)
Definition: gdbarch.c:1491
const struct regset ppcobsd_fpregset
Definition: ppc-obsd-tdep.c:77
PTRACE_TYPE_RET ptrace()
static void ppcobsd_store_registers(struct target_ops *ops, struct regcache *regcache, int regnum)
Definition: ppc-obsd-nat.c:109
static bool getfpregs_supplies(struct gdbarch *gdbarch, int regnum)
void ppc_collect_gregset(const struct regset *regset, const struct regcache *regcache, int regnum, void *gregs, size_t len)
Definition: rs6000-tdep.c:675
int gdbarch_sp_regnum(struct gdbarch *gdbarch)
Definition: gdbarch.c:2146
int ppc_gp0_regnum
Definition: ppc-tdep.h:227
void ppc_collect_fpregset(const struct regset *regset, const struct regcache *regcache, int regnum, void *fpregs, size_t len)
Definition: rs6000-tdep.c:726
struct ppc_reg_offsets ppcobsd_reg_offsets
Definition: ppc-obsd-tdep.c:36
int regnum
Definition: aarch64-tdep.c:77
void read_memory(CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
Definition: corefile.c:258
Definition: regdef.h:22
#define gdb_assert(expr)
Definition: gdb_assert.h:32
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:457
void void void void void void void void void perror_with_name(const char *string) ATTRIBUTE_NORETURN
Definition: utils.c:692
static void ppcobsd_fetch_registers(struct target_ops *ops, struct regcache *regcache, int regnum)
Definition: ppc-obsd-nat.c:74
gdbarch * arch() const
Definition: regcache.c:221
void regcache_raw_supply(struct regcache *regcache, int regnum, const void *buf)
Definition: regcache.c:1004
static int ppcobsd_supply_pcb(struct regcache *regcache, struct pcb *pcb)
Definition: ppc-obsd-nat.c:148
int gdbarch_pc_regnum(struct gdbarch *gdbarch)
Definition: gdbarch.c:2163
#define PTRACE_TYPE_ARG3
Definition: config.h:642
void _initialize_ppcobsd_nat(void)
Definition: ppc-obsd-nat.c:185
void bsd_kvm_add_target(int(*supply_pcb)(struct regcache *, struct pcb *))
Definition: bsd-kvm.c:354
void(* to_store_registers)(struct target_ops *, struct regcache *, int) TARGET_DEFAULT_NORETURN(noprocess())
Definition: target.h:459
int ppc_floating_point_unit_p(struct gdbarch *gdbarch)
Definition: rs6000-tdep.c:218
int ppc_fp0_regnum
Definition: ppc-tdep.h:240
void ppc_supply_gregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *gregs, size_t len)
Definition: rs6000-tdep.c:511