]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/spu-multiarch.c
Remove regcache_get_ptid
[thirdparty/binutils-gdb.git] / gdb / spu-multiarch.c
CommitLineData
85e747d2 1/* Cell SPU GNU/Linux multi-architecture debugging support.
e2882c85 2 Copyright (C) 2009-2018 Free Software Foundation, Inc.
85e747d2
UW
3
4 Contributed by Ulrich Weigand <uweigand@de.ibm.com>.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
dcf7800b 10 the Free Software Foundation; either version 3 of the License, or
85e747d2
UW
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
dcf7800b 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
85e747d2
UW
20
21#include "defs.h"
22#include "gdbcore.h"
23#include "gdbcmd.h"
85e747d2 24#include "arch-utils.h"
76727919 25#include "observable.h"
85e747d2
UW
26#include "inferior.h"
27#include "regcache.h"
28#include "symfile.h"
29#include "objfiles.h"
30#include "solib.h"
31#include "solist.h"
32
33#include "ppc-tdep.h"
34#include "ppc-linux-tdep.h"
35#include "spu-tdep.h"
36
f6ac5f3d
PA
37/* The SPU multi-architecture support target. */
38
d9f719f1
PA
39static const target_info spu_multiarch_target_info = {
40 "spu",
41 N_("SPU multi-architecture support."),
42 N_("SPU multi-architecture support.")
43};
44
f6ac5f3d
PA
45struct spu_multiarch_target final : public target_ops
46{
47 spu_multiarch_target ()
48 { to_stratum = arch_stratum; };
49
d9f719f1
PA
50 const target_info &info () const override
51 { return spu_multiarch_target_info; }
f6ac5f3d
PA
52
53 void mourn_inferior () override;
54
57810aa7 55 void fetch_registers (struct regcache *, int) override;
f6ac5f3d
PA
56 void store_registers (struct regcache *, int) override;
57
58 enum target_xfer_status xfer_partial (enum target_object object,
59 const char *annex,
60 gdb_byte *readbuf,
61 const gdb_byte *writebuf,
62 ULONGEST offset, ULONGEST len,
63 ULONGEST *xfered_len) override;
64
65 int search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
66 const gdb_byte *pattern, ULONGEST pattern_len,
67 CORE_ADDR *found_addrp) override;
68
69 int region_ok_for_hw_watchpoint (CORE_ADDR, int) override;
70
71 struct gdbarch *thread_architecture (ptid_t) override;
72};
73
74static spu_multiarch_target spu_ops;
85e747d2
UW
75
76/* Number of SPE objects loaded into the current inferior. */
77static int spu_nr_solib;
78
79/* Stand-alone SPE executable? */
80#define spu_standalone_p() \
81 (symfile_objfile && symfile_objfile->obfd \
82 && bfd_get_arch (symfile_objfile->obfd) == bfd_arch_spu)
83
84/* PPU side system calls. */
85#define INSTR_SC 0x44000002
86#define NR_spu_run 0x0116
87
88/* If the PPU thread is currently stopped on a spu_run system call,
89 return to FD and ADDR the file handle and NPC parameter address
90 used with the system call. Return non-zero if successful. */
91static int
92parse_spufs_run (ptid_t ptid, int *fd, CORE_ADDR *addr)
93{
f5656ead 94 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
85e747d2
UW
95 struct gdbarch_tdep *tdep;
96 struct regcache *regcache;
e362b510 97 gdb_byte buf[4];
85e747d2
UW
98 ULONGEST regval;
99
100 /* If we're not on PPU, there's nothing to detect. */
f5656ead 101 if (gdbarch_bfd_arch_info (target_gdbarch ())->arch != bfd_arch_powerpc)
85e747d2
UW
102 return 0;
103
791bb1f4
UW
104 /* If we're called too early (e.g. after fork), we cannot
105 access the inferior yet. */
106 if (find_inferior_ptid (ptid) == NULL)
107 return 0;
108
85e747d2 109 /* Get PPU-side registers. */
f5656ead
TT
110 regcache = get_thread_arch_regcache (ptid, target_gdbarch ());
111 tdep = gdbarch_tdep (target_gdbarch ());
85e747d2
UW
112
113 /* Fetch instruction preceding current NIP. */
2989a365
TT
114 {
115 scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
116 inferior_ptid = ptid;
117 regval = target_read_memory (regcache_read_pc (regcache) - 4, buf, 4);
118 }
791bb1f4 119 if (regval != 0)
85e747d2
UW
120 return 0;
121 /* It should be a "sc" instruction. */
122 if (extract_unsigned_integer (buf, 4, byte_order) != INSTR_SC)
123 return 0;
124 /* System call number should be NR_spu_run. */
125 regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum, &regval);
126 if (regval != NR_spu_run)
127 return 0;
128
129 /* Register 3 contains fd, register 4 the NPC param pointer. */
130 regcache_cooked_read_unsigned (regcache, PPC_ORIG_R3_REGNUM, &regval);
131 *fd = (int) regval;
132 regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum + 4, &regval);
133 *addr = (CORE_ADDR) regval;
134 return 1;
135}
136
137/* Find gdbarch for SPU context SPUFS_FD. */
138static struct gdbarch *
139spu_gdbarch (int spufs_fd)
140{
141 struct gdbarch_info info;
142 gdbarch_info_init (&info);
143 info.bfd_arch_info = bfd_lookup_arch (bfd_arch_spu, bfd_mach_spu);
144 info.byte_order = BFD_ENDIAN_BIG;
145 info.osabi = GDB_OSABI_LINUX;
0dba2a6c 146 info.id = &spufs_fd;
85e747d2
UW
147 return gdbarch_find_by_info (info);
148}
149
150/* Override the to_thread_architecture routine. */
f6ac5f3d
PA
151struct gdbarch *
152spu_multiarch_target::thread_architecture (ptid_t ptid)
85e747d2
UW
153{
154 int spufs_fd;
155 CORE_ADDR spufs_addr;
156
157 if (parse_spufs_run (ptid, &spufs_fd, &spufs_addr))
158 return spu_gdbarch (spufs_fd);
159
f6ac5f3d
PA
160 target_ops *beneath = find_target_beneath (this);
161 return beneath->thread_architecture (ptid);
85e747d2
UW
162}
163
164/* Override the to_region_ok_for_hw_watchpoint routine. */
57810aa7 165
f6ac5f3d
PA
166int
167spu_multiarch_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
85e747d2 168{
f6ac5f3d 169 struct target_ops *ops_beneath = find_target_beneath (this);
85e747d2
UW
170
171 /* We cannot watch SPU local store. */
172 if (SPUADDR_SPU (addr) != -1)
173 return 0;
174
f6ac5f3d 175 return ops_beneath->region_ok_for_hw_watchpoint (addr, len);
85e747d2
UW
176}
177
178/* Override the to_fetch_registers routine. */
f6ac5f3d
PA
179
180void
181spu_multiarch_target::fetch_registers (struct regcache *regcache, int regno)
85e747d2 182{
ac7936df 183 struct gdbarch *gdbarch = regcache->arch ();
85e747d2 184 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
f6ac5f3d 185 struct target_ops *ops_beneath = find_target_beneath (this);
85e747d2
UW
186 int spufs_fd;
187 CORE_ADDR spufs_addr;
188
639a9038
SM
189 /* Since we use functions that rely on inferior_ptid, we need to set and
190 restore it. */
191 scoped_restore save_ptid
222312d3 192 = make_scoped_restore (&inferior_ptid, regcache->ptid ());
639a9038 193
85e747d2
UW
194 /* This version applies only if we're currently in spu_run. */
195 if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_spu)
196 {
f6ac5f3d 197 ops_beneath->fetch_registers (regcache, regno);
85e747d2
UW
198 return;
199 }
200
201 /* We must be stopped on a spu_run system call. */
202 if (!parse_spufs_run (inferior_ptid, &spufs_fd, &spufs_addr))
203 return;
204
205 /* The ID register holds the spufs file handle. */
206 if (regno == -1 || regno == SPU_ID_REGNUM)
207 {
e362b510 208 gdb_byte buf[4];
85e747d2
UW
209 store_unsigned_integer (buf, 4, byte_order, spufs_fd);
210 regcache_raw_supply (regcache, SPU_ID_REGNUM, buf);
211 }
212
213 /* The NPC register is found in PPC memory at SPUFS_ADDR. */
214 if (regno == -1 || regno == SPU_PC_REGNUM)
215 {
e362b510 216 gdb_byte buf[4];
85e747d2
UW
217
218 if (target_read (ops_beneath, TARGET_OBJECT_MEMORY, NULL,
219 buf, spufs_addr, sizeof buf) == sizeof buf)
220 regcache_raw_supply (regcache, SPU_PC_REGNUM, buf);
221 }
222
223 /* The GPRs are found in the "regs" spufs file. */
224 if (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))
225 {
e362b510
PA
226 gdb_byte buf[16 * SPU_NUM_GPRS];
227 char annex[32];
85e747d2
UW
228 int i;
229
230 xsnprintf (annex, sizeof annex, "%d/regs", spufs_fd);
231 if (target_read (ops_beneath, TARGET_OBJECT_SPU, annex,
232 buf, 0, sizeof buf) == sizeof buf)
233 for (i = 0; i < SPU_NUM_GPRS; i++)
234 regcache_raw_supply (regcache, i, buf + i*16);
235 }
236}
237
238/* Override the to_store_registers routine. */
f6ac5f3d
PA
239
240void
241spu_multiarch_target::store_registers (struct regcache *regcache, int regno)
85e747d2 242{
ac7936df 243 struct gdbarch *gdbarch = regcache->arch ();
f6ac5f3d 244 struct target_ops *ops_beneath = find_target_beneath (this);
85e747d2
UW
245 int spufs_fd;
246 CORE_ADDR spufs_addr;
247
639a9038
SM
248 /* Since we use functions that rely on inferior_ptid, we need to set and
249 restore it. */
250 scoped_restore save_ptid
222312d3 251 = make_scoped_restore (&inferior_ptid, regcache->ptid ());
639a9038 252
85e747d2
UW
253 /* This version applies only if we're currently in spu_run. */
254 if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_spu)
255 {
f6ac5f3d 256 ops_beneath->store_registers (regcache, regno);
85e747d2
UW
257 return;
258 }
259
260 /* We must be stopped on a spu_run system call. */
261 if (!parse_spufs_run (inferior_ptid, &spufs_fd, &spufs_addr))
262 return;
263
264 /* The NPC register is found in PPC memory at SPUFS_ADDR. */
265 if (regno == -1 || regno == SPU_PC_REGNUM)
266 {
e362b510 267 gdb_byte buf[4];
85e747d2
UW
268 regcache_raw_collect (regcache, SPU_PC_REGNUM, buf);
269
270 target_write (ops_beneath, TARGET_OBJECT_MEMORY, NULL,
271 buf, spufs_addr, sizeof buf);
272 }
273
274 /* The GPRs are found in the "regs" spufs file. */
275 if (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))
276 {
e362b510
PA
277 gdb_byte buf[16 * SPU_NUM_GPRS];
278 char annex[32];
85e747d2
UW
279 int i;
280
281 for (i = 0; i < SPU_NUM_GPRS; i++)
282 regcache_raw_collect (regcache, i, buf + i*16);
283
284 xsnprintf (annex, sizeof annex, "%d/regs", spufs_fd);
285 target_write (ops_beneath, TARGET_OBJECT_SPU, annex,
286 buf, 0, sizeof buf);
287 }
288}
289
290/* Override the to_xfer_partial routine. */
f6ac5f3d
PA
291
292enum target_xfer_status
293spu_multiarch_target::xfer_partial (enum target_object object,
294 const char *annex, gdb_byte *readbuf,
295 const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
296 ULONGEST *xfered_len)
85e747d2 297{
f6ac5f3d 298 struct target_ops *ops_beneath = find_target_beneath (this);
85e747d2
UW
299
300 /* Use the "mem" spufs file to access SPU local store. */
301 if (object == TARGET_OBJECT_MEMORY)
302 {
303 int fd = SPUADDR_SPU (offset);
304 CORE_ADDR addr = SPUADDR_ADDR (offset);
d2ed6730
UW
305 char mem_annex[32], lslr_annex[32];
306 gdb_byte buf[32];
307 ULONGEST lslr;
9b409511 308 enum target_xfer_status ret;
85e747d2 309
d2ed6730 310 if (fd >= 0)
85e747d2
UW
311 {
312 xsnprintf (mem_annex, sizeof mem_annex, "%d/mem", fd);
f6ac5f3d
PA
313 ret = ops_beneath->xfer_partial (TARGET_OBJECT_SPU,
314 mem_annex, readbuf, writebuf,
315 addr, len, xfered_len);
9b409511 316 if (ret == TARGET_XFER_OK)
d2ed6730
UW
317 return ret;
318
319 /* SPU local store access wraps the address around at the
320 local store limit. We emulate this here. To avoid needing
321 an extra access to retrieve the LSLR, we only do that after
322 trying the original address first, and getting end-of-file. */
323 xsnprintf (lslr_annex, sizeof lslr_annex, "%d/lslr", fd);
324 memset (buf, 0, sizeof buf);
f6ac5f3d
PA
325 if (ops_beneath->xfer_partial (TARGET_OBJECT_SPU,
326 lslr_annex, buf, NULL,
327 0, sizeof buf, xfered_len)
9b409511 328 != TARGET_XFER_OK)
d2ed6730
UW
329 return ret;
330
001f13d8 331 lslr = strtoulst ((char *) buf, NULL, 16);
f6ac5f3d
PA
332 return ops_beneath->xfer_partial (TARGET_OBJECT_SPU,
333 mem_annex, readbuf, writebuf,
334 addr & lslr, len, xfered_len);
85e747d2
UW
335 }
336 }
337
f6ac5f3d
PA
338 return ops_beneath->xfer_partial (object, annex,
339 readbuf, writebuf, offset, len, xfered_len);
85e747d2
UW
340}
341
342/* Override the to_search_memory routine. */
f6ac5f3d
PA
343int
344spu_multiarch_target::search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
345 const gdb_byte *pattern, ULONGEST pattern_len,
346 CORE_ADDR *found_addrp)
85e747d2 347{
f6ac5f3d 348 struct target_ops *ops_beneath = find_target_beneath (this);
85e747d2 349
e75fdfca
TT
350 /* For SPU local store, always fall back to the simple method. */
351 if (SPUADDR_SPU (start_addr) >= 0)
f6ac5f3d 352 return simple_search_memory (this, start_addr, search_space_len,
85e747d2
UW
353 pattern, pattern_len, found_addrp);
354
f6ac5f3d
PA
355 return ops_beneath->search_memory (start_addr, search_space_len,
356 pattern, pattern_len, found_addrp);
85e747d2
UW
357}
358
359
360/* Push and pop the SPU multi-architecture support target. */
361
362static void
363spu_multiarch_activate (void)
364{
365 /* If GDB was configured without SPU architecture support,
366 we cannot install SPU multi-architecture support either. */
367 if (spu_gdbarch (-1) == NULL)
368 return;
369
370 push_target (&spu_ops);
371
372 /* Make sure the thread architecture is re-evaluated. */
373 registers_changed ();
374}
375
376static void
377spu_multiarch_deactivate (void)
378{
379 unpush_target (&spu_ops);
380
381 /* Make sure the thread architecture is re-evaluated. */
382 registers_changed ();
383}
384
385static void
386spu_multiarch_inferior_created (struct target_ops *ops, int from_tty)
387{
388 if (spu_standalone_p ())
389 spu_multiarch_activate ();
390}
391
392static void
393spu_multiarch_solib_loaded (struct so_list *so)
394{
395 if (!spu_standalone_p ())
396 if (so->abfd && bfd_get_arch (so->abfd) == bfd_arch_spu)
397 if (spu_nr_solib++ == 0)
398 spu_multiarch_activate ();
399}
400
401static void
402spu_multiarch_solib_unloaded (struct so_list *so)
403{
404 if (!spu_standalone_p ())
405 if (so->abfd && bfd_get_arch (so->abfd) == bfd_arch_spu)
406 if (--spu_nr_solib == 0)
407 spu_multiarch_deactivate ();
408}
409
f6ac5f3d
PA
410void
411spu_multiarch_target::mourn_inferior ()
85e747d2 412{
f6ac5f3d 413 struct target_ops *ops_beneath = find_target_beneath (this);
85e747d2 414
f6ac5f3d 415 ops_beneath->mourn_inferior ();
85e747d2
UW
416 spu_multiarch_deactivate ();
417}
418
85e747d2
UW
419void
420_initialize_spu_multiarch (void)
421{
85e747d2 422 /* Install observers to watch for SPU objects. */
76727919
TT
423 gdb::observers::inferior_created.attach (spu_multiarch_inferior_created);
424 gdb::observers::solib_loaded.attach (spu_multiarch_solib_loaded);
425 gdb::observers::solib_unloaded.attach (spu_multiarch_solib_unloaded);
85e747d2
UW
426}
427