GDB (xrefs)
/tmp/gdb-7.10/gdb/sparc-nat.c
Go to the documentation of this file.
1 /* Native-dependent code for SPARC.
2 
3  Copyright (C) 2003-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 "inferior.h"
22 #include "regcache.h"
23 #include "target.h"
24 
25 #include <signal.h>
26 #include <sys/ptrace.h>
27 #include "gdb_wait.h"
28 #ifdef HAVE_MACHINE_REG_H
29 #include <machine/reg.h>
30 #endif
31 
32 #include "sparc-tdep.h"
33 #include "sparc-nat.h"
34 #include "inf-ptrace.h"
35 
36 /* With some trickery we can use the code in this file for most (if
37  not all) ptrace(2) based SPARC systems, which includes SunOS 4,
38  GNU/Linux and the various SPARC BSD's.
39 
40  First, we need a data structure for use with ptrace(2). SunOS has
41  `struct regs' and `struct fp_status' in <machine/reg.h>. BSD's
42  have `struct reg' and `struct fpreg' in <machine/reg.h>. GNU/Linux
43  has the same structures as SunOS 4, but they're in <asm/reg.h>,
44  which is a kernel header. As a general rule we avoid including
45  GNU/Linux kernel headers. Fortunately GNU/Linux has a `gregset_t'
46  and a `fpregset_t' that are equivalent to `struct regs' and `struct
47  fp_status' in <sys/ucontext.h>, which is automatically included by
48  <signal.h>. Settling on using the `gregset_t' and `fpregset_t'
49  typedefs, providing them for the other systems, therefore solves
50  the puzzle. */
51 
52 #ifdef HAVE_MACHINE_REG_H
53 #ifdef HAVE_STRUCT_REG
54 typedef struct reg gregset_t;
55 typedef struct fpreg fpregset_t;
56 #else
57 typedef struct regs gregset_t;
58 typedef struct fp_status fpregset_t;
59 #endif
60 #endif
61 
62 /* Second, we need to remap the BSD ptrace(2) requests to their SunOS
63  equivalents. GNU/Linux already follows SunOS here. */
64 
65 #ifndef PTRACE_GETREGS
66 #define PTRACE_GETREGS PT_GETREGS
67 #endif
68 
69 #ifndef PTRACE_SETREGS
70 #define PTRACE_SETREGS PT_SETREGS
71 #endif
72 
73 #ifndef PTRACE_GETFPREGS
74 #define PTRACE_GETFPREGS PT_GETFPREGS
75 #endif
76 
77 #ifndef PTRACE_SETFPREGS
78 #define PTRACE_SETFPREGS PT_SETFPREGS
79 #endif
80 
81 /* Register set description. */
82 const struct sparc_gregmap *sparc_gregmap;
83 const struct sparc_fpregmap *sparc_fpregmap;
84 void (*sparc_supply_gregset) (const struct sparc_gregmap *,
85  struct regcache *, int , const void *);
86 void (*sparc_collect_gregset) (const struct sparc_gregmap *,
87  const struct regcache *, int, void *);
88 void (*sparc_supply_fpregset) (const struct sparc_fpregmap *,
89  struct regcache *, int , const void *);
90 void (*sparc_collect_fpregset) (const struct sparc_fpregmap *,
91  const struct regcache *, int , void *);
94 
95 /* Determine whether `gregset_t' contains register REGNUM. */
96 
97 int
99 {
100  /* Integer registers. */
101  if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_G7_REGNUM)
102  || (regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM)
103  || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_L7_REGNUM)
104  || (regnum >= SPARC_I0_REGNUM && regnum <= SPARC_I7_REGNUM))
105  return 1;
106 
107  /* Control registers. */
108  if (regnum == SPARC32_PC_REGNUM
109  || regnum == SPARC32_NPC_REGNUM
110  || regnum == SPARC32_PSR_REGNUM
111  || regnum == SPARC32_Y_REGNUM)
112  return 1;
113 
114  return 0;
115 }
116 
117 /* Determine whether `fpregset_t' contains register REGNUM. */
118 
119 int
121 {
122  /* Floating-point registers. */
123  if (regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM)
124  return 1;
125 
126  /* Control registers. */
127  if (regnum == SPARC32_FSR_REGNUM)
128  return 1;
129 
130  return 0;
131 }
132 
133 /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
134  for all registers (including the floating-point registers). */
135 
136 void
138  struct regcache *regcache, int regnum)
139 {
140  struct gdbarch *gdbarch = get_regcache_arch (regcache);
141  int pid;
142 
143  /* NOTE: cagney/2002-12-03: This code assumes that the currently
144  selected light weight processes' registers can be written
145  directly into the selected thread's register cache. This works
146  fine when given an 1:1 LWP:thread model (such as found on
147  GNU/Linux) but will, likely, have problems when used on an N:1
148  (userland threads) or N:M (userland multiple LWP) model. In the
149  case of the latter two, the LWP's registers do not necessarily
150  belong to the selected thread (the LWP could be in the middle of
151  executing the thread switch code).
152 
153  These functions should instead be paramaterized with an explicit
154  object (struct regcache, struct thread_info?) into which the LWPs
155  registers can be written. */
156  pid = ptid_get_lwp (inferior_ptid);
157  if (pid == 0)
158  pid = ptid_get_pid (inferior_ptid);
159 
160  if (regnum == SPARC_G0_REGNUM)
161  {
162  gdb_byte zero[8] = { 0 };
163 
164  regcache_raw_supply (regcache, SPARC_G0_REGNUM, &zero);
165  return;
166  }
167 
168  if (regnum == -1 || sparc_gregset_supplies_p (gdbarch, regnum))
169  {
170  gregset_t regs;
171 
172  if (ptrace (PTRACE_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
173  perror_with_name (_("Couldn't get registers"));
174 
175  sparc_supply_gregset (sparc_gregmap, regcache, -1, &regs);
176  if (regnum != -1)
177  return;
178  }
179 
180  if (regnum == -1 || sparc_fpregset_supplies_p (gdbarch, regnum))
181  {
182  fpregset_t fpregs;
183 
184  if (ptrace (PTRACE_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
185  perror_with_name (_("Couldn't get floating point status"));
186 
187  sparc_supply_fpregset (sparc_fpregmap, regcache, -1, &fpregs);
188  }
189 }
190 
191 void
193  struct regcache *regcache, int regnum)
194 {
195  struct gdbarch *gdbarch = get_regcache_arch (regcache);
196  int pid;
197 
198  /* NOTE: cagney/2002-12-02: See comment in fetch_inferior_registers
199  about threaded assumptions. */
200  pid = ptid_get_lwp (inferior_ptid);
201  if (pid == 0)
202  pid = ptid_get_pid (inferior_ptid);
203 
204  if (regnum == -1 || sparc_gregset_supplies_p (gdbarch, regnum))
205  {
206  gregset_t regs;
207 
208  if (ptrace (PTRACE_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
209  perror_with_name (_("Couldn't get registers"));
210 
211  sparc_collect_gregset (sparc_gregmap, regcache, regnum, &regs);
212 
213  if (ptrace (PTRACE_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
214  perror_with_name (_("Couldn't write registers"));
215 
216  /* Deal with the stack regs. */
217  if (regnum == -1 || regnum == SPARC_SP_REGNUM
218  || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM))
219  {
220  ULONGEST sp;
221 
223  sparc_collect_rwindow (regcache, sp, regnum);
224  }
225 
226  if (regnum != -1)
227  return;
228  }
229 
230  if (regnum == -1 || sparc_fpregset_supplies_p (gdbarch, regnum))
231  {
232  fpregset_t fpregs, saved_fpregs;
233 
234  if (ptrace (PTRACE_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
235  perror_with_name (_("Couldn't get floating-point registers"));
236 
237  memcpy (&saved_fpregs, &fpregs, sizeof (fpregs));
238  sparc_collect_fpregset (sparc_fpregmap, regcache, regnum, &fpregs);
239 
240  /* Writing the floating-point registers will fail on NetBSD with
241  EINVAL if the inferior process doesn't have an FPU state
242  (i.e. if it didn't use the FPU yet). Therefore we don't try
243  to write the registers if nothing changed. */
244  if (memcmp (&saved_fpregs, &fpregs, sizeof (fpregs)) != 0)
245  {
246  if (ptrace (PTRACE_SETFPREGS, pid,
247  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
248  perror_with_name (_("Couldn't write floating-point registers"));
249  }
250 
251  if (regnum != -1)
252  return;
253  }
254 }
255 
256 
257 /* Implement the to_xfer_partial target_ops method for
258  TARGET_OBJECT_WCOOKIE. Fetch StackGhost Per-Process XOR cookie. */
259 
260 static enum target_xfer_status
261 sparc_xfer_wcookie (struct target_ops *ops, enum target_object object,
262  const char *annex, gdb_byte *readbuf,
263  const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
264  ULONGEST *xfered_len)
265 {
266  unsigned long wcookie = 0;
267  char *buf = (char *)&wcookie;
268 
269  gdb_assert (object == TARGET_OBJECT_WCOOKIE);
270  gdb_assert (readbuf && writebuf == NULL);
271 
272  if (offset == sizeof (unsigned long))
273  return TARGET_XFER_EOF; /* Signal EOF. */
274  if (offset > sizeof (unsigned long))
275  return TARGET_XFER_E_IO;
276 
277 #ifdef PT_WCOOKIE
278  /* If PT_WCOOKIE is defined (by <sys/ptrace.h>), assume we're
279  running on an OpenBSD release that uses StackGhost (3.1 or
280  later). Since release 3.6, OpenBSD uses a fully randomized
281  cookie. */
282  {
284 
285  /* Sanity check. The proper type for a cookie is register_t, but
286  we can't assume that this type exists on all systems supported
287  by the code in this file. */
288  gdb_assert (sizeof (wcookie) == sizeof (register_t));
289 
290  /* Fetch the cookie. */
291  if (ptrace (PT_WCOOKIE, pid, (PTRACE_TYPE_ARG3) &wcookie, 0) == -1)
292  {
293  if (errno != EINVAL)
294  perror_with_name (_("Couldn't get StackGhost cookie"));
295 
296  /* Although PT_WCOOKIE is defined on OpenBSD 3.1 and later,
297  the request wasn't implemented until after OpenBSD 3.4. If
298  the kernel doesn't support the PT_WCOOKIE request, assume
299  we're running on a kernel that uses non-randomized cookies. */
300  wcookie = 0x3;
301  }
302  }
303 #endif /* PT_WCOOKIE */
304 
305  if (len > sizeof (unsigned long) - offset)
306  len = sizeof (unsigned long) - offset;
307 
308  memcpy (readbuf, buf + offset, len);
309  *xfered_len = (ULONGEST) len;
310  return TARGET_XFER_OK;
311 }
312 
314 
315 static enum target_xfer_status
316 sparc_xfer_partial (struct target_ops *ops, enum target_object object,
317  const char *annex, gdb_byte *readbuf,
318  const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
319  ULONGEST *xfered_len)
320 {
321  if (object == TARGET_OBJECT_WCOOKIE)
322  return sparc_xfer_wcookie (ops, object, annex, readbuf, writebuf,
323  offset, len, xfered_len);
324 
325  return inf_ptrace_xfer_partial (ops, object, annex, readbuf, writebuf,
326  offset, len, xfered_len);
327 }
328 
329 /* Create a prototype generic SPARC target. The client can override
330  it with local methods. */
331 
332 struct target_ops *
334 {
335  struct target_ops *t;
336 
337  t = inf_ptrace_target ();
342  return t;
343 }
344 
345 
346 /* Provide a prototype to silence -Wmissing-prototypes. */
347 void _initialize_sparc_nat (void);
348 
349 void
351 {
352  /* Deafult to using SunOS 4 register sets. */
353  if (sparc_gregmap == NULL)
354  sparc_gregmap = &sparc32_sunos4_gregmap;
355  if (sparc_fpregmap == NULL)
356  sparc_fpregmap = &sparc32_sunos4_fpregmap;
357  if (sparc_supply_gregset == NULL)
359  if (sparc_collect_gregset == NULL)
361  if (sparc_supply_fpregset == NULL)
363  if (sparc_collect_fpregset == NULL)
365  if (sparc_gregset_supplies_p == NULL)
367  if (sparc_fpregset_supplies_p == NULL)
369 }
int sparc32_gregset_supplies_p(struct gdbarch *gdbarch, int regnum)
Definition: sparc-nat.c:98
void(* sparc_collect_fpregset)(const struct sparc_fpregmap *, const struct regcache *, int, void *)
Definition: sparc-nat.c:90
const struct sparc_gregmap * sparc_gregmap
Definition: sparc-nat.c:82
void sparc32_supply_gregset(const struct sparc_gregmap *gregmap, struct regcache *regcache, int regnum, const void *gregs)
Definition: sparc-tdep.c:1894
struct gdbarch * get_regcache_arch(const struct regcache *regcache)
Definition: regcache.c:297
#define PTRACE_GETFPREGS
Definition: sparc-nat.c:74
#define PTRACE_SETREGS
Definition: sparc-nat.c:70
struct target_ops * sparc_target(void)
Definition: sparc-nat.c:333
int sparc32_fpregset_supplies_p(struct gdbarch *gdbarch, int regnum)
Definition: sparc-nat.c:120
void(* sparc_collect_gregset)(const struct sparc_gregmap *, const struct regcache *, int, void *)
Definition: sparc-nat.c:86
void sparc_store_inferior_registers(struct target_ops *ops, struct regcache *regcache, int regnum)
Definition: sparc-nat.c:192
void sparc32_collect_fpregset(const struct sparc_fpregmap *fpregmap, const struct regcache *regcache, int regnum, void *fpregs)
Definition: sparc-tdep.c:2034
#define _(String)
Definition: gdb_locale.h:40
struct target_ops * inf_ptrace_target(void)
Definition: inf-ptrace.c:668
PTRACE_TYPE_RET ptrace()
#define PTRACE_GETREGS
Definition: sparc-nat.c:66
const struct sparc_fpregmap * sparc_fpregmap
Definition: sparc-nat.c:83
void sparc_collect_rwindow(const struct regcache *regcache, CORE_ADDR sp, int regnum)
Definition: sparc-tdep.c:1823
enum register_status regcache_cooked_read_unsigned(struct regcache *regcache, int regnum, ULONGEST *val)
Definition: regcache.c:837
const struct sparc_fpregmap sparc32_sunos4_fpregmap
Definition: sparc-tdep.c:2069
void sparc_fetch_inferior_registers(struct target_ops *ops, struct regcache *regcache, int regnum)
Definition: sparc-nat.c:137
target_xfer_status
Definition: target.h:219
void sparc32_supply_fpregset(const struct sparc_fpregmap *fpregmap, struct regcache *regcache, int regnum, const void *fpregs)
Definition: sparc-tdep.c:2014
enum target_xfer_status target_xfer_partial_ftype(struct target_ops *ops, enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
#define gdb_assert(expr)
Definition: gdb_assert.h:33
enum target_xfer_status(* to_xfer_partial)(struct target_ops *ops, enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) TARGET_DEFAULT_RETURN(TARGET_XFER_E_IO)
Definition: target.h:724
void sparc32_collect_gregset(const struct sparc_gregmap *gregmap, const struct regcache *regcache, int regnum, void *gregs)
Definition: sparc-tdep.c:1959
int regnum
Definition: aarch64-tdep.c:69
const struct sparc_gregmap sparc32_sunos4_gregmap
Definition: sparc-tdep.c:2057
target_object
Definition: target.h:136
Definition: regdef.h:22
int ptid_get_pid(ptid_t ptid)
Definition: ptid.c:52
const char const char int
Definition: command.h:229
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
void(* sparc_supply_fpregset)(const struct sparc_fpregmap *, struct regcache *, int, const void *)
Definition: sparc-nat.c:88
ptid_t inferior_ptid
Definition: infcmd.c:124
static enum target_xfer_status sparc_xfer_wcookie(struct target_ops *ops, enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
Definition: sparc-nat.c:261
#define PTRACE_SETFPREGS
Definition: sparc-nat.c:78
int offset
Definition: agent.c:65
void _initialize_sparc_nat(void)
Definition: sparc-nat.c:350
target_xfer_partial_ftype * inf_ptrace_xfer_partial
Definition: sparc-nat.c:313
void regcache_raw_supply(struct regcache *regcache, int regnum, const void *buf)
Definition: regcache.c:1041
int(* sparc_fpregset_supplies_p)(struct gdbarch *, int)
Definition: sparc-nat.c:93
unsigned long long ULONGEST
Definition: common-types.h:53
long ptid_get_lwp(ptid_t ptid)
Definition: ptid.c:60
#define PTRACE_TYPE_ARG3
Definition: config.h:658
int(* sparc_gregset_supplies_p)(struct gdbarch *, int)
Definition: sparc-nat.c:92
void(* to_store_registers)(struct target_ops *, struct regcache *, int) TARGET_DEFAULT_NORETURN(noprocess())
Definition: target.h:474
void(* sparc_supply_gregset)(const struct sparc_gregmap *, struct regcache *, int, const void *)
Definition: sparc-nat.c:84
static enum target_xfer_status sparc_xfer_partial(struct target_ops *ops, enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
Definition: sparc-nat.c:316
struct fpreg fpregset_t
Definition: alphabsd-nat.c:41
mach_port_t mach_port_t name mach_port_t mach_port_t name error_t int int rusage_t pid_t pid
Definition: gnu-nat.c:1818
const ULONGEST const LONGEST len
Definition: target.h:309