GDB (xrefs)
Loading...
Searching...
No Matches
sparc-nat.c
Go to the documentation of this file.
1/* Native-dependent code for SPARC.
2
3 Copyright (C) 2003-2023 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 "gdbsupport/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
54typedef struct reg gregset_t;
55typedef struct fpreg fpregset_t;
56#else
57typedef struct regs gregset_t;
58typedef 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
81static PTRACE_TYPE_RET
82gdb_ptrace (PTRACE_TYPE_ARG1 request, ptid_t ptid, PTRACE_TYPE_ARG3 addr)
83{
84#ifdef __NetBSD__
85 /* Support for NetBSD threads: unlike other ptrace implementations in this
86 file, NetBSD requires that we pass both the pid and lwp. */
87 return ptrace (request, ptid.pid (), addr, ptid.lwp ());
88#else
89 pid_t pid = get_ptrace_pid (ptid);
90 return ptrace (request, pid, addr, 0);
91#endif
92}
93
94/* Register set description. */
97void (*sparc_supply_gregset) (const struct sparc_gregmap *,
98 struct regcache *, int , const void *);
99void (*sparc_collect_gregset) (const struct sparc_gregmap *,
100 const struct regcache *, int, void *);
101void (*sparc_supply_fpregset) (const struct sparc_fpregmap *,
102 struct regcache *, int , const void *);
104 const struct regcache *, int , void *);
105int (*sparc_gregset_supplies_p) (struct gdbarch *, int);
106int (*sparc_fpregset_supplies_p) (struct gdbarch *, int);
107
108/* Determine whether `gregset_t' contains register REGNUM. */
109
110int
112{
113 /* Integer registers. */
118 return 1;
119
120 /* Control registers. */
125 return 1;
126
127 return 0;
128}
129
130/* Determine whether `fpregset_t' contains register REGNUM. */
131
132int
134{
135 /* Floating-point registers. */
137 return 1;
138
139 /* Control registers. */
141 return 1;
142
143 return 0;
144}
145
146/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
147 for all registers (including the floating-point registers). */
148
149void
152{
153 struct gdbarch *gdbarch = regcache->arch ();
154 ptid_t ptid = regcache->ptid ();
155
156 if (regnum == SPARC_G0_REGNUM)
157 {
158 gdb_byte zero[8] = { 0 };
159
161 return;
162 }
163
165 {
166 gregset_t regs;
167
168 if (gdb_ptrace (PTRACE_GETREGS, ptid, (PTRACE_TYPE_ARG3) &regs) == -1)
169 perror_with_name (_("Couldn't get registers"));
170
171 /* Deep down, sparc_supply_rwindow reads memory, so needs the global
172 thread context to be set. */
173 scoped_restore restore_inferior_ptid
174 = make_scoped_restore (&inferior_ptid, ptid);
175
177 if (regnum != -1)
178 return;
179 }
180
182 {
183 fpregset_t fpregs;
184
185 if (gdb_ptrace (PTRACE_GETFPREGS, ptid, (PTRACE_TYPE_ARG3) &fpregs) == -1)
186 perror_with_name (_("Couldn't get floating point status"));
187
189 }
190}
191
192void
195{
196 struct gdbarch *gdbarch = regcache->arch ();
197 ptid_t ptid = regcache->ptid ();
198
200 {
201 gregset_t regs;
202
203 if (gdb_ptrace (PTRACE_GETREGS, ptid, (PTRACE_TYPE_ARG3) &regs) == -1)
204 perror_with_name (_("Couldn't get registers"));
205
207
208 if (gdb_ptrace (PTRACE_SETREGS, ptid, (PTRACE_TYPE_ARG3) &regs) == -1)
209 perror_with_name (_("Couldn't write registers"));
210
211 /* Deal with the stack regs. */
212 if (regnum == -1 || regnum == SPARC_SP_REGNUM
214 {
215 ULONGEST sp;
216
218
219 /* Deep down, sparc_collect_rwindow writes memory, so needs the global
220 thread context to be set. */
221 scoped_restore restore_inferior_ptid
222 = make_scoped_restore (&inferior_ptid, ptid);
223
225 }
226
227 if (regnum != -1)
228 return;
229 }
230
232 {
233 fpregset_t fpregs, saved_fpregs;
234
235 if (gdb_ptrace (PTRACE_GETFPREGS, ptid, (PTRACE_TYPE_ARG3) &fpregs) == -1)
236 perror_with_name (_("Couldn't get floating-point registers"));
237
238 memcpy (&saved_fpregs, &fpregs, sizeof (fpregs));
240
241 /* Writing the floating-point registers will fail on NetBSD with
242 EINVAL if the inferior process doesn't have an FPU state
243 (i.e. if it didn't use the FPU yet). Therefore we don't try
244 to write the registers if nothing changed. */
245 if (memcmp (&saved_fpregs, &fpregs, sizeof (fpregs)) != 0)
246 {
247 if (gdb_ptrace (PTRACE_SETFPREGS, ptid,
248 (PTRACE_TYPE_ARG3) &fpregs) == -1)
249 perror_with_name (_("Couldn't write floating-point registers"));
250 }
251
252 if (regnum != -1)
253 return;
254 }
255}
256
257
258/* Implement the to_xfer_partial target_ops method for
259 TARGET_OBJECT_WCOOKIE. Fetch StackGhost Per-Process XOR cookie. */
260
263 const char *annex, gdb_byte *readbuf,
264 const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
265 ULONGEST *xfered_len)
266{
267 unsigned long wcookie = 0;
268 char *buf = (char *)&wcookie;
269
270 gdb_assert (object == TARGET_OBJECT_WCOOKIE);
271 gdb_assert (readbuf && writebuf == NULL);
272
273 if (offset == sizeof (unsigned long))
274 return TARGET_XFER_EOF; /* Signal EOF. */
275 if (offset > sizeof (unsigned long))
276 return TARGET_XFER_E_IO;
277
278#ifdef PT_WCOOKIE
279 /* If PT_WCOOKIE is defined (by <sys/ptrace.h>), assume we're
280 running on an OpenBSD release that uses StackGhost (3.1 or
281 later). Since release 3.6, OpenBSD uses a fully randomized
282 cookie. */
283 {
284 int pid = inferior_ptid.pid ();
285
286 /* Sanity check. The proper type for a cookie is register_t, but
287 we can't assume that this type exists on all systems supported
288 by the code in this file. */
289 gdb_assert (sizeof (wcookie) == sizeof (register_t));
290
291 /* Fetch the cookie. */
292 if (ptrace (PT_WCOOKIE, pid, (PTRACE_TYPE_ARG3) &wcookie, 0) == -1)
293 {
294 if (errno != EINVAL)
295 perror_with_name (_("Couldn't get StackGhost cookie"));
296
297 /* Although PT_WCOOKIE is defined on OpenBSD 3.1 and later,
298 the request wasn't implemented until after OpenBSD 3.4. If
299 the kernel doesn't support the PT_WCOOKIE request, assume
300 we're running on a kernel that uses non-randomized cookies. */
301 wcookie = 0x3;
302 }
303 }
304#endif /* PT_WCOOKIE */
305
306 if (len > sizeof (unsigned long) - offset)
307 len = sizeof (unsigned long) - offset;
308
309 memcpy (readbuf, buf + offset, len);
310 *xfered_len = (ULONGEST) len;
311 return TARGET_XFER_OK;
312}
313
314
316void
int regnum
gdbarch * arch() const
Definition regcache.c:231
void raw_supply(int regnum, const void *buf) override
Definition regcache.c:1062
ptid_t ptid() const
Definition regcache.h:408
#define PTRACE_TYPE_RET
Definition config.h:675
#define PTRACE_TYPE_ARG1
Definition config.h:663
#define ptrace(request, pid, addr, data)
Definition gdb_ptrace.h:141
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:1791
pid_t get_ptrace_pid(ptid_t ptid)
Definition inf-ptrace.c:238
ptid_t inferior_ptid
Definition infcmd.c:74
#define PTRACE_TYPE_ARG3
enum register_status regcache_cooked_read_unsigned(struct regcache *regcache, int regnum, ULONGEST *val)
Definition regcache.c:796
#define PTRACE_GETREGS
Definition sparc-nat.c:66
int sparc32_fpregset_supplies_p(struct gdbarch *gdbarch, int regnum)
Definition sparc-nat.c:133
const struct sparc_gregmap * sparc_gregmap
Definition sparc-nat.c:95
void(* sparc_collect_gregset)(const struct sparc_gregmap *, const struct regcache *, int, void *)
Definition sparc-nat.c:99
int(* sparc_fpregset_supplies_p)(struct gdbarch *, int)
Definition sparc-nat.c:106
void _initialize_sparc_nat()
Definition sparc-nat.c:317
void sparc_store_inferior_registers(process_stratum_target *proc_target, regcache *regcache, int regnum)
Definition sparc-nat.c:193
int sparc32_gregset_supplies_p(struct gdbarch *gdbarch, int regnum)
Definition sparc-nat.c:111
const struct sparc_fpregmap * sparc_fpregmap
Definition sparc-nat.c:96
static PTRACE_TYPE_RET gdb_ptrace(PTRACE_TYPE_ARG1 request, ptid_t ptid, PTRACE_TYPE_ARG3 addr)
Definition sparc-nat.c:82
#define PTRACE_GETFPREGS
Definition sparc-nat.c:74
void(* sparc_collect_fpregset)(const struct sparc_fpregmap *, const struct regcache *, int, void *)
Definition sparc-nat.c:103
#define PTRACE_SETREGS
Definition sparc-nat.c:70
#define PTRACE_SETFPREGS
Definition sparc-nat.c:78
int(* sparc_gregset_supplies_p)(struct gdbarch *, int)
Definition sparc-nat.c:105
void(* sparc_supply_fpregset)(const struct sparc_fpregmap *, struct regcache *, int, const void *)
Definition sparc-nat.c:101
void(* sparc_supply_gregset)(const struct sparc_gregmap *, struct regcache *, int, const void *)
Definition sparc-nat.c:97
void sparc_fetch_inferior_registers(process_stratum_target *proc_target, regcache *regcache, int regnum)
Definition sparc-nat.c:150
enum target_xfer_status sparc_xfer_wcookie(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:262
void sparc_collect_rwindow(const struct regcache *regcache, CORE_ADDR sp, int regnum)
void sparc32_supply_gregset(const struct sparc_gregmap *gregmap, struct regcache *regcache, int regnum, const void *gregs)
const struct sparc_fpregmap sparc32_sunos4_fpregmap
const struct sparc_gregmap sparc32_sunos4_gregmap
void sparc32_supply_fpregset(const struct sparc_fpregmap *fpregmap, struct regcache *regcache, int regnum, const void *fpregs)
void sparc32_collect_fpregset(const struct sparc_fpregmap *fpregmap, const struct regcache *regcache, int regnum, void *fpregs)
void sparc32_collect_gregset(const struct sparc_gregmap *gregmap, const struct regcache *regcache, int regnum, void *gregs)
@ SPARC32_NPC_REGNUM
Definition sparc-tdep.h:156
@ SPARC32_FSR_REGNUM
Definition sparc-tdep.h:157
@ SPARC32_PSR_REGNUM
Definition sparc-tdep.h:152
@ SPARC32_PC_REGNUM
Definition sparc-tdep.h:155
@ SPARC32_Y_REGNUM
Definition sparc-tdep.h:150
@ SPARC_O0_REGNUM
Definition sparc-tdep.h:112
@ SPARC_G0_REGNUM
Definition sparc-tdep.h:104
@ SPARC_G1_REGNUM
Definition sparc-tdep.h:105
@ SPARC_L0_REGNUM
Definition sparc-tdep.h:120
@ SPARC_I0_REGNUM
Definition sparc-tdep.h:128
@ SPARC_G7_REGNUM
Definition sparc-tdep.h:111
@ SPARC_F0_REGNUM
Definition sparc-tdep.h:136
@ SPARC_L7_REGNUM
Definition sparc-tdep.h:127
@ SPARC_I7_REGNUM
Definition sparc-tdep.h:135
@ SPARC_F31_REGNUM
Definition sparc-tdep.h:144
@ SPARC_O7_REGNUM
Definition sparc-tdep.h:119
@ SPARC_SP_REGNUM
Definition sparc-tdep.h:118
target_xfer_status
Definition target.h:219
@ TARGET_XFER_E_IO
Definition target.h:232
@ TARGET_XFER_EOF
Definition target.h:224
@ TARGET_XFER_OK
Definition target.h:221
target_object
Definition target.h:143
@ TARGET_OBJECT_WCOOKIE
Definition target.h:164