1 /* Cell SPU GNU/Linux multi-architecture debugging support.
2 Copyright (C) 2009-2019 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 static const target_info spu_multiarch_target_info = {
41 N_("SPU multi-architecture support."),
42 N_("SPU multi-architecture support.")
45 struct spu_multiarch_target final : public target_ops
47 const target_info &info () const override
48 { return spu_multiarch_target_info; }
50 strata stratum () const override { return arch_stratum; }
52 void mourn_inferior () override;
54 void fetch_registers (struct regcache *, int) override;
55 void store_registers (struct regcache *, int) override;
57 enum target_xfer_status xfer_partial (enum target_object object,
60 const gdb_byte *writebuf,
61 ULONGEST offset, ULONGEST len,
62 ULONGEST *xfered_len) override;
64 int search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
65 const gdb_byte *pattern, ULONGEST pattern_len,
66 CORE_ADDR *found_addrp) override;
68 int region_ok_for_hw_watchpoint (CORE_ADDR, int) override;
70 struct gdbarch *thread_architecture (ptid_t) override;
73 static spu_multiarch_target spu_ops;
75 /* Number of SPE objects loaded into the current inferior. */
76 static int spu_nr_solib;
78 /* Stand-alone SPE executable? */
79 #define spu_standalone_p() \
80 (symfile_objfile && symfile_objfile->obfd \
81 && bfd_get_arch (symfile_objfile->obfd) == bfd_arch_spu)
83 /* PPU side system calls. */
84 #define INSTR_SC 0x44000002
85 #define NR_spu_run 0x0116
87 /* If the PPU thread is currently stopped on a spu_run system call,
88 return to FD and ADDR the file handle and NPC parameter address
89 used with the system call. Return non-zero if successful. */
91 parse_spufs_run (ptid_t ptid, int *fd, CORE_ADDR *addr)
93 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
94 struct gdbarch_tdep *tdep;
95 struct regcache *regcache;
99 /* If we're not on PPU, there's nothing to detect. */
100 if (gdbarch_bfd_arch_info (target_gdbarch ())->arch != bfd_arch_powerpc)
103 /* If we're called too early (e.g. after fork), we cannot
104 access the inferior yet. */
105 if (find_inferior_ptid (ptid) == NULL)
108 /* Get PPU-side registers. */
109 regcache = get_thread_arch_regcache (ptid, target_gdbarch ());
110 tdep = gdbarch_tdep (target_gdbarch ());
112 /* Fetch instruction preceding current NIP. */
114 scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
115 inferior_ptid = ptid;
116 regval = target_read_memory (regcache_read_pc (regcache) - 4, buf, 4);
120 /* It should be a "sc" instruction. */
121 if (extract_unsigned_integer (buf, 4, byte_order) != INSTR_SC)
123 /* System call number should be NR_spu_run. */
124 regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum, ®val);
125 if (regval != NR_spu_run)
128 /* Register 3 contains fd, register 4 the NPC param pointer. */
129 regcache_cooked_read_unsigned (regcache, PPC_ORIG_R3_REGNUM, ®val);
131 regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum + 4, ®val);
132 *addr = (CORE_ADDR) regval;
136 /* Find gdbarch for SPU context SPUFS_FD. */
137 static struct gdbarch *
138 spu_gdbarch (int spufs_fd)
140 struct gdbarch_info info;
141 gdbarch_info_init (&info);
142 info.bfd_arch_info = bfd_lookup_arch (bfd_arch_spu, bfd_mach_spu);
143 info.byte_order = BFD_ENDIAN_BIG;
144 info.osabi = GDB_OSABI_LINUX;
146 return gdbarch_find_by_info (info);
149 /* Override the to_thread_architecture routine. */
151 spu_multiarch_target::thread_architecture (ptid_t ptid)
154 CORE_ADDR spufs_addr;
156 if (parse_spufs_run (ptid, &spufs_fd, &spufs_addr))
157 return spu_gdbarch (spufs_fd);
159 return beneath ()->thread_architecture (ptid);
162 /* Override the to_region_ok_for_hw_watchpoint routine. */
165 spu_multiarch_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
167 /* We cannot watch SPU local store. */
168 if (SPUADDR_SPU (addr) != -1)
171 return beneath ()->region_ok_for_hw_watchpoint (addr, len);
174 /* Override the to_fetch_registers routine. */
177 spu_multiarch_target::fetch_registers (struct regcache *regcache, int regno)
179 struct gdbarch *gdbarch = regcache->arch ();
180 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
182 CORE_ADDR spufs_addr;
184 /* Since we use functions that rely on inferior_ptid, we need to set and
186 scoped_restore save_ptid
187 = make_scoped_restore (&inferior_ptid, regcache->ptid ());
189 /* This version applies only if we're currently in spu_run. */
190 if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_spu)
192 beneath ()->fetch_registers (regcache, regno);
196 /* We must be stopped on a spu_run system call. */
197 if (!parse_spufs_run (inferior_ptid, &spufs_fd, &spufs_addr))
200 /* The ID register holds the spufs file handle. */
201 if (regno == -1 || regno == SPU_ID_REGNUM)
204 store_unsigned_integer (buf, 4, byte_order, spufs_fd);
205 regcache->raw_supply (SPU_ID_REGNUM, buf);
208 /* The NPC register is found in PPC memory at SPUFS_ADDR. */
209 if (regno == -1 || regno == SPU_PC_REGNUM)
213 if (target_read (beneath (), TARGET_OBJECT_MEMORY, NULL,
214 buf, spufs_addr, sizeof buf) == sizeof buf)
215 regcache->raw_supply (SPU_PC_REGNUM, buf);
218 /* The GPRs are found in the "regs" spufs file. */
219 if (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))
221 gdb_byte buf[16 * SPU_NUM_GPRS];
225 xsnprintf (annex, sizeof annex, "%d/regs", spufs_fd);
226 if (target_read (beneath (), TARGET_OBJECT_SPU, annex,
227 buf, 0, sizeof buf) == sizeof buf)
228 for (i = 0; i < SPU_NUM_GPRS; i++)
229 regcache->raw_supply (i, buf + i*16);
233 /* Override the to_store_registers routine. */
236 spu_multiarch_target::store_registers (struct regcache *regcache, int regno)
238 struct gdbarch *gdbarch = regcache->arch ();
240 CORE_ADDR spufs_addr;
242 /* Since we use functions that rely on inferior_ptid, we need to set and
244 scoped_restore save_ptid
245 = make_scoped_restore (&inferior_ptid, regcache->ptid ());
247 /* This version applies only if we're currently in spu_run. */
248 if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_spu)
250 beneath ()->store_registers (regcache, regno);
254 /* We must be stopped on a spu_run system call. */
255 if (!parse_spufs_run (inferior_ptid, &spufs_fd, &spufs_addr))
258 /* The NPC register is found in PPC memory at SPUFS_ADDR. */
259 if (regno == -1 || regno == SPU_PC_REGNUM)
262 regcache->raw_collect (SPU_PC_REGNUM, buf);
264 target_write (beneath (), TARGET_OBJECT_MEMORY, NULL,
265 buf, spufs_addr, sizeof buf);
268 /* The GPRs are found in the "regs" spufs file. */
269 if (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))
271 gdb_byte buf[16 * SPU_NUM_GPRS];
275 for (i = 0; i < SPU_NUM_GPRS; i++)
276 regcache->raw_collect (i, buf + i*16);
278 xsnprintf (annex, sizeof annex, "%d/regs", spufs_fd);
279 target_write (beneath (), TARGET_OBJECT_SPU, annex,
284 /* Override the to_xfer_partial routine. */
286 enum target_xfer_status
287 spu_multiarch_target::xfer_partial (enum target_object object,
288 const char *annex, gdb_byte *readbuf,
289 const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
290 ULONGEST *xfered_len)
292 struct target_ops *ops_beneath = this->beneath ();
294 /* Use the "mem" spufs file to access SPU local store. */
295 if (object == TARGET_OBJECT_MEMORY)
297 int fd = SPUADDR_SPU (offset);
298 CORE_ADDR addr = SPUADDR_ADDR (offset);
299 char mem_annex[32], lslr_annex[32];
302 enum target_xfer_status ret;
306 xsnprintf (mem_annex, sizeof mem_annex, "%d/mem", fd);
307 ret = ops_beneath->xfer_partial (TARGET_OBJECT_SPU,
308 mem_annex, readbuf, writebuf,
309 addr, len, xfered_len);
310 if (ret == TARGET_XFER_OK)
313 /* SPU local store access wraps the address around at the
314 local store limit. We emulate this here. To avoid needing
315 an extra access to retrieve the LSLR, we only do that after
316 trying the original address first, and getting end-of-file. */
317 xsnprintf (lslr_annex, sizeof lslr_annex, "%d/lslr", fd);
318 memset (buf, 0, sizeof buf);
319 if (ops_beneath->xfer_partial (TARGET_OBJECT_SPU,
320 lslr_annex, buf, NULL,
321 0, sizeof buf, xfered_len)
325 lslr = strtoulst ((char *) buf, NULL, 16);
326 return ops_beneath->xfer_partial (TARGET_OBJECT_SPU,
327 mem_annex, readbuf, writebuf,
328 addr & lslr, len, xfered_len);
332 return ops_beneath->xfer_partial (object, annex,
333 readbuf, writebuf, offset, len, xfered_len);
336 /* Override the to_search_memory routine. */
338 spu_multiarch_target::search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
339 const gdb_byte *pattern, ULONGEST pattern_len,
340 CORE_ADDR *found_addrp)
342 /* For SPU local store, always fall back to the simple method. */
343 if (SPUADDR_SPU (start_addr) >= 0)
344 return simple_search_memory (this, start_addr, search_space_len,
345 pattern, pattern_len, found_addrp);
347 return beneath ()->search_memory (start_addr, search_space_len,
348 pattern, pattern_len, found_addrp);
352 /* Push and pop the SPU multi-architecture support target. */
355 spu_multiarch_activate (void)
357 /* If GDB was configured without SPU architecture support,
358 we cannot install SPU multi-architecture support either. */
359 if (spu_gdbarch (-1) == NULL)
362 push_target (&spu_ops);
364 /* Make sure the thread architecture is re-evaluated. */
365 registers_changed ();
369 spu_multiarch_deactivate (void)
371 unpush_target (&spu_ops);
373 /* Make sure the thread architecture is re-evaluated. */
374 registers_changed ();
378 spu_multiarch_inferior_created (struct target_ops *ops, int from_tty)
380 if (spu_standalone_p ())
381 spu_multiarch_activate ();
385 spu_multiarch_solib_loaded (struct so_list *so)
387 if (!spu_standalone_p ())
388 if (so->abfd && bfd_get_arch (so->abfd) == bfd_arch_spu)
389 if (spu_nr_solib++ == 0)
390 spu_multiarch_activate ();
394 spu_multiarch_solib_unloaded (struct so_list *so)
396 if (!spu_standalone_p ())
397 if (so->abfd && bfd_get_arch (so->abfd) == bfd_arch_spu)
398 if (--spu_nr_solib == 0)
399 spu_multiarch_deactivate ();
403 spu_multiarch_target::mourn_inferior ()
405 beneath ()->mourn_inferior ();
406 spu_multiarch_deactivate ();
410 _initialize_spu_multiarch (void)
412 /* Install observers to watch for SPU objects. */
413 gdb::observers::inferior_created.attach (spu_multiarch_inferior_created);
414 gdb::observers::solib_loaded.attach (spu_multiarch_solib_loaded);
415 gdb::observers::solib_unloaded.attach (spu_multiarch_solib_unloaded);