1 /* Cell SPU GNU/Linux multi-architecture debugging support.
2 Copyright (C) 2009-2018 Free Software Foundation, Inc.
4 Contributed by Ulrich Weigand <uweigand@de.ibm.com>.
6 This file is part of GDB.
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
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
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.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 #include "arch-utils.h"
25 #include "observable.h"
34 #include "ppc-linux-tdep.h"
37 /* The SPU multi-architecture support target. */
39 struct spu_multiarch_target final
: public target_ops
41 spu_multiarch_target ()
42 { to_stratum
= arch_stratum
; };
44 const char *shortname () override
47 const char *longname () override
48 { return _("SPU multi-architecture support."); }
50 const char *doc () override
51 { return _("SPU multi-architecture support."); }
53 void mourn_inferior () override
;
55 void fetch_registers (struct regcache
*, int) override
;
56 void store_registers (struct regcache
*, int) override
;
58 enum target_xfer_status
xfer_partial (enum target_object object
,
61 const gdb_byte
*writebuf
,
62 ULONGEST offset
, ULONGEST len
,
63 ULONGEST
*xfered_len
) override
;
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
;
69 int region_ok_for_hw_watchpoint (CORE_ADDR
, int) override
;
71 struct gdbarch
*thread_architecture (ptid_t
) override
;
74 static spu_multiarch_target spu_ops
;
76 /* Number of SPE objects loaded into the current inferior. */
77 static int spu_nr_solib
;
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)
84 /* PPU side system calls. */
85 #define INSTR_SC 0x44000002
86 #define NR_spu_run 0x0116
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. */
92 parse_spufs_run (ptid_t ptid
, int *fd
, CORE_ADDR
*addr
)
94 enum bfd_endian byte_order
= gdbarch_byte_order (target_gdbarch ());
95 struct gdbarch_tdep
*tdep
;
96 struct regcache
*regcache
;
100 /* If we're not on PPU, there's nothing to detect. */
101 if (gdbarch_bfd_arch_info (target_gdbarch ())->arch
!= bfd_arch_powerpc
)
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
)
109 /* Get PPU-side registers. */
110 regcache
= get_thread_arch_regcache (ptid
, target_gdbarch ());
111 tdep
= gdbarch_tdep (target_gdbarch ());
113 /* Fetch instruction preceding current NIP. */
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);
121 /* It should be a "sc" instruction. */
122 if (extract_unsigned_integer (buf
, 4, byte_order
) != INSTR_SC
)
124 /* System call number should be NR_spu_run. */
125 regcache_cooked_read_unsigned (regcache
, tdep
->ppc_gp0_regnum
, ®val
);
126 if (regval
!= NR_spu_run
)
129 /* Register 3 contains fd, register 4 the NPC param pointer. */
130 regcache_cooked_read_unsigned (regcache
, PPC_ORIG_R3_REGNUM
, ®val
);
132 regcache_cooked_read_unsigned (regcache
, tdep
->ppc_gp0_regnum
+ 4, ®val
);
133 *addr
= (CORE_ADDR
) regval
;
137 /* Find gdbarch for SPU context SPUFS_FD. */
138 static struct gdbarch
*
139 spu_gdbarch (int spufs_fd
)
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
;
147 return gdbarch_find_by_info (info
);
150 /* Override the to_thread_architecture routine. */
152 spu_multiarch_target::thread_architecture (ptid_t ptid
)
155 CORE_ADDR spufs_addr
;
157 if (parse_spufs_run (ptid
, &spufs_fd
, &spufs_addr
))
158 return spu_gdbarch (spufs_fd
);
160 target_ops
*beneath
= find_target_beneath (this);
161 return beneath
->thread_architecture (ptid
);
164 /* Override the to_region_ok_for_hw_watchpoint routine. */
167 spu_multiarch_target::region_ok_for_hw_watchpoint (CORE_ADDR addr
, int len
)
169 struct target_ops
*ops_beneath
= find_target_beneath (this);
171 /* We cannot watch SPU local store. */
172 if (SPUADDR_SPU (addr
) != -1)
175 return ops_beneath
->region_ok_for_hw_watchpoint (addr
, len
);
178 /* Override the to_fetch_registers routine. */
181 spu_multiarch_target::fetch_registers (struct regcache
*regcache
, int regno
)
183 struct gdbarch
*gdbarch
= regcache
->arch ();
184 enum bfd_endian byte_order
= gdbarch_byte_order (gdbarch
);
185 struct target_ops
*ops_beneath
= find_target_beneath (this);
187 CORE_ADDR spufs_addr
;
189 /* Since we use functions that rely on inferior_ptid, we need to set and
191 scoped_restore save_ptid
192 = make_scoped_restore (&inferior_ptid
, regcache_get_ptid (regcache
));
194 /* This version applies only if we're currently in spu_run. */
195 if (gdbarch_bfd_arch_info (gdbarch
)->arch
!= bfd_arch_spu
)
197 ops_beneath
->fetch_registers (regcache
, regno
);
201 /* We must be stopped on a spu_run system call. */
202 if (!parse_spufs_run (inferior_ptid
, &spufs_fd
, &spufs_addr
))
205 /* The ID register holds the spufs file handle. */
206 if (regno
== -1 || regno
== SPU_ID_REGNUM
)
209 store_unsigned_integer (buf
, 4, byte_order
, spufs_fd
);
210 regcache_raw_supply (regcache
, SPU_ID_REGNUM
, buf
);
213 /* The NPC register is found in PPC memory at SPUFS_ADDR. */
214 if (regno
== -1 || regno
== SPU_PC_REGNUM
)
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
);
223 /* The GPRs are found in the "regs" spufs file. */
224 if (regno
== -1 || (regno
>= 0 && regno
< SPU_NUM_GPRS
))
226 gdb_byte buf
[16 * SPU_NUM_GPRS
];
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);
238 /* Override the to_store_registers routine. */
241 spu_multiarch_target::store_registers (struct regcache
*regcache
, int regno
)
243 struct gdbarch
*gdbarch
= regcache
->arch ();
244 struct target_ops
*ops_beneath
= find_target_beneath (this);
246 CORE_ADDR spufs_addr
;
248 /* Since we use functions that rely on inferior_ptid, we need to set and
250 scoped_restore save_ptid
251 = make_scoped_restore (&inferior_ptid
, regcache_get_ptid (regcache
));
253 /* This version applies only if we're currently in spu_run. */
254 if (gdbarch_bfd_arch_info (gdbarch
)->arch
!= bfd_arch_spu
)
256 ops_beneath
->store_registers (regcache
, regno
);
260 /* We must be stopped on a spu_run system call. */
261 if (!parse_spufs_run (inferior_ptid
, &spufs_fd
, &spufs_addr
))
264 /* The NPC register is found in PPC memory at SPUFS_ADDR. */
265 if (regno
== -1 || regno
== SPU_PC_REGNUM
)
268 regcache_raw_collect (regcache
, SPU_PC_REGNUM
, buf
);
270 target_write (ops_beneath
, TARGET_OBJECT_MEMORY
, NULL
,
271 buf
, spufs_addr
, sizeof buf
);
274 /* The GPRs are found in the "regs" spufs file. */
275 if (regno
== -1 || (regno
>= 0 && regno
< SPU_NUM_GPRS
))
277 gdb_byte buf
[16 * SPU_NUM_GPRS
];
281 for (i
= 0; i
< SPU_NUM_GPRS
; i
++)
282 regcache_raw_collect (regcache
, i
, buf
+ i
*16);
284 xsnprintf (annex
, sizeof annex
, "%d/regs", spufs_fd
);
285 target_write (ops_beneath
, TARGET_OBJECT_SPU
, annex
,
290 /* Override the to_xfer_partial routine. */
292 enum target_xfer_status
293 spu_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
)
298 struct target_ops
*ops_beneath
= find_target_beneath (this);
300 /* Use the "mem" spufs file to access SPU local store. */
301 if (object
== TARGET_OBJECT_MEMORY
)
303 int fd
= SPUADDR_SPU (offset
);
304 CORE_ADDR addr
= SPUADDR_ADDR (offset
);
305 char mem_annex
[32], lslr_annex
[32];
308 enum target_xfer_status ret
;
312 xsnprintf (mem_annex
, sizeof mem_annex
, "%d/mem", fd
);
313 ret
= ops_beneath
->xfer_partial (TARGET_OBJECT_SPU
,
314 mem_annex
, readbuf
, writebuf
,
315 addr
, len
, xfered_len
);
316 if (ret
== TARGET_XFER_OK
)
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
);
325 if (ops_beneath
->xfer_partial (TARGET_OBJECT_SPU
,
326 lslr_annex
, buf
, NULL
,
327 0, sizeof buf
, xfered_len
)
331 lslr
= strtoulst ((char *) buf
, NULL
, 16);
332 return ops_beneath
->xfer_partial (TARGET_OBJECT_SPU
,
333 mem_annex
, readbuf
, writebuf
,
334 addr
& lslr
, len
, xfered_len
);
338 return ops_beneath
->xfer_partial (object
, annex
,
339 readbuf
, writebuf
, offset
, len
, xfered_len
);
342 /* Override the to_search_memory routine. */
344 spu_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
)
348 struct target_ops
*ops_beneath
= find_target_beneath (this);
350 /* For SPU local store, always fall back to the simple method. */
351 if (SPUADDR_SPU (start_addr
) >= 0)
352 return simple_search_memory (this, start_addr
, search_space_len
,
353 pattern
, pattern_len
, found_addrp
);
355 return ops_beneath
->search_memory (start_addr
, search_space_len
,
356 pattern
, pattern_len
, found_addrp
);
360 /* Push and pop the SPU multi-architecture support target. */
363 spu_multiarch_activate (void)
365 /* If GDB was configured without SPU architecture support,
366 we cannot install SPU multi-architecture support either. */
367 if (spu_gdbarch (-1) == NULL
)
370 push_target (&spu_ops
);
372 /* Make sure the thread architecture is re-evaluated. */
373 registers_changed ();
377 spu_multiarch_deactivate (void)
379 unpush_target (&spu_ops
);
381 /* Make sure the thread architecture is re-evaluated. */
382 registers_changed ();
386 spu_multiarch_inferior_created (struct target_ops
*ops
, int from_tty
)
388 if (spu_standalone_p ())
389 spu_multiarch_activate ();
393 spu_multiarch_solib_loaded (struct so_list
*so
)
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 ();
402 spu_multiarch_solib_unloaded (struct so_list
*so
)
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 ();
411 spu_multiarch_target::mourn_inferior ()
413 struct target_ops
*ops_beneath
= find_target_beneath (this);
415 ops_beneath
->mourn_inferior ();
416 spu_multiarch_deactivate ();
420 _initialize_spu_multiarch (void)
422 /* Install observers to watch for SPU objects. */
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
);