make-target-delegates: line break between return type and function name
[deliverable/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
39struct spu_multiarch_target final : public target_ops
40{
41 spu_multiarch_target ()
42 { to_stratum = arch_stratum; };
43
44 const char *shortname () override
45 { return "spu"; }
46
47 const char *longname () override
48 { return _("SPU multi-architecture support."); }
49
50 const char *doc () override
51 { return _("SPU multi-architecture support."); }
52
53 void mourn_inferior () override;
54
55 void fetch_registers (struct regcache *, int) override;
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. */
f6ac5f3d
PA
165int
166spu_multiarch_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
85e747d2 167{
f6ac5f3d 168 struct target_ops *ops_beneath = find_target_beneath (this);
85e747d2
UW
169
170 /* We cannot watch SPU local store. */
171 if (SPUADDR_SPU (addr) != -1)
172 return 0;
173
f6ac5f3d 174 return ops_beneath->region_ok_for_hw_watchpoint (addr, len);
85e747d2
UW
175}
176
177/* Override the to_fetch_registers routine. */
f6ac5f3d
PA
178
179void
180spu_multiarch_target::fetch_registers (struct regcache *regcache, int regno)
85e747d2 181{
ac7936df 182 struct gdbarch *gdbarch = regcache->arch ();
85e747d2 183 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
f6ac5f3d 184 struct target_ops *ops_beneath = find_target_beneath (this);
85e747d2
UW
185 int spufs_fd;
186 CORE_ADDR spufs_addr;
187
639a9038
SM
188 /* Since we use functions that rely on inferior_ptid, we need to set and
189 restore it. */
190 scoped_restore save_ptid
191 = make_scoped_restore (&inferior_ptid, regcache_get_ptid (regcache));
192
85e747d2
UW
193 /* This version applies only if we're currently in spu_run. */
194 if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_spu)
195 {
f6ac5f3d 196 ops_beneath->fetch_registers (regcache, regno);
85e747d2
UW
197 return;
198 }
199
200 /* We must be stopped on a spu_run system call. */
201 if (!parse_spufs_run (inferior_ptid, &spufs_fd, &spufs_addr))
202 return;
203
204 /* The ID register holds the spufs file handle. */
205 if (regno == -1 || regno == SPU_ID_REGNUM)
206 {
e362b510 207 gdb_byte buf[4];
85e747d2
UW
208 store_unsigned_integer (buf, 4, byte_order, spufs_fd);
209 regcache_raw_supply (regcache, SPU_ID_REGNUM, buf);
210 }
211
212 /* The NPC register is found in PPC memory at SPUFS_ADDR. */
213 if (regno == -1 || regno == SPU_PC_REGNUM)
214 {
e362b510 215 gdb_byte buf[4];
85e747d2
UW
216
217 if (target_read (ops_beneath, TARGET_OBJECT_MEMORY, NULL,
218 buf, spufs_addr, sizeof buf) == sizeof buf)
219 regcache_raw_supply (regcache, SPU_PC_REGNUM, buf);
220 }
221
222 /* The GPRs are found in the "regs" spufs file. */
223 if (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))
224 {
e362b510
PA
225 gdb_byte buf[16 * SPU_NUM_GPRS];
226 char annex[32];
85e747d2
UW
227 int i;
228
229 xsnprintf (annex, sizeof annex, "%d/regs", spufs_fd);
230 if (target_read (ops_beneath, TARGET_OBJECT_SPU, annex,
231 buf, 0, sizeof buf) == sizeof buf)
232 for (i = 0; i < SPU_NUM_GPRS; i++)
233 regcache_raw_supply (regcache, i, buf + i*16);
234 }
235}
236
237/* Override the to_store_registers routine. */
f6ac5f3d
PA
238
239void
240spu_multiarch_target::store_registers (struct regcache *regcache, int regno)
85e747d2 241{
ac7936df 242 struct gdbarch *gdbarch = regcache->arch ();
f6ac5f3d 243 struct target_ops *ops_beneath = find_target_beneath (this);
85e747d2
UW
244 int spufs_fd;
245 CORE_ADDR spufs_addr;
246
639a9038
SM
247 /* Since we use functions that rely on inferior_ptid, we need to set and
248 restore it. */
249 scoped_restore save_ptid
250 = make_scoped_restore (&inferior_ptid, regcache_get_ptid (regcache));
251
85e747d2
UW
252 /* This version applies only if we're currently in spu_run. */
253 if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_spu)
254 {
f6ac5f3d 255 ops_beneath->store_registers (regcache, regno);
85e747d2
UW
256 return;
257 }
258
259 /* We must be stopped on a spu_run system call. */
260 if (!parse_spufs_run (inferior_ptid, &spufs_fd, &spufs_addr))
261 return;
262
263 /* The NPC register is found in PPC memory at SPUFS_ADDR. */
264 if (regno == -1 || regno == SPU_PC_REGNUM)
265 {
e362b510 266 gdb_byte buf[4];
85e747d2
UW
267 regcache_raw_collect (regcache, SPU_PC_REGNUM, buf);
268
269 target_write (ops_beneath, TARGET_OBJECT_MEMORY, NULL,
270 buf, spufs_addr, sizeof buf);
271 }
272
273 /* The GPRs are found in the "regs" spufs file. */
274 if (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))
275 {
e362b510
PA
276 gdb_byte buf[16 * SPU_NUM_GPRS];
277 char annex[32];
85e747d2
UW
278 int i;
279
280 for (i = 0; i < SPU_NUM_GPRS; i++)
281 regcache_raw_collect (regcache, i, buf + i*16);
282
283 xsnprintf (annex, sizeof annex, "%d/regs", spufs_fd);
284 target_write (ops_beneath, TARGET_OBJECT_SPU, annex,
285 buf, 0, sizeof buf);
286 }
287}
288
289/* Override the to_xfer_partial routine. */
f6ac5f3d
PA
290
291enum target_xfer_status
292spu_multiarch_target::xfer_partial (enum target_object object,
293 const char *annex, gdb_byte *readbuf,
294 const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
295 ULONGEST *xfered_len)
85e747d2 296{
f6ac5f3d 297 struct target_ops *ops_beneath = find_target_beneath (this);
85e747d2
UW
298
299 /* Use the "mem" spufs file to access SPU local store. */
300 if (object == TARGET_OBJECT_MEMORY)
301 {
302 int fd = SPUADDR_SPU (offset);
303 CORE_ADDR addr = SPUADDR_ADDR (offset);
d2ed6730
UW
304 char mem_annex[32], lslr_annex[32];
305 gdb_byte buf[32];
306 ULONGEST lslr;
9b409511 307 enum target_xfer_status ret;
85e747d2 308
d2ed6730 309 if (fd >= 0)
85e747d2
UW
310 {
311 xsnprintf (mem_annex, sizeof mem_annex, "%d/mem", fd);
f6ac5f3d
PA
312 ret = ops_beneath->xfer_partial (TARGET_OBJECT_SPU,
313 mem_annex, readbuf, writebuf,
314 addr, len, xfered_len);
9b409511 315 if (ret == TARGET_XFER_OK)
d2ed6730
UW
316 return ret;
317
318 /* SPU local store access wraps the address around at the
319 local store limit. We emulate this here. To avoid needing
320 an extra access to retrieve the LSLR, we only do that after
321 trying the original address first, and getting end-of-file. */
322 xsnprintf (lslr_annex, sizeof lslr_annex, "%d/lslr", fd);
323 memset (buf, 0, sizeof buf);
f6ac5f3d
PA
324 if (ops_beneath->xfer_partial (TARGET_OBJECT_SPU,
325 lslr_annex, buf, NULL,
326 0, sizeof buf, xfered_len)
9b409511 327 != TARGET_XFER_OK)
d2ed6730
UW
328 return ret;
329
001f13d8 330 lslr = strtoulst ((char *) buf, NULL, 16);
f6ac5f3d
PA
331 return ops_beneath->xfer_partial (TARGET_OBJECT_SPU,
332 mem_annex, readbuf, writebuf,
333 addr & lslr, len, xfered_len);
85e747d2
UW
334 }
335 }
336
f6ac5f3d
PA
337 return ops_beneath->xfer_partial (object, annex,
338 readbuf, writebuf, offset, len, xfered_len);
85e747d2
UW
339}
340
341/* Override the to_search_memory routine. */
f6ac5f3d
PA
342int
343spu_multiarch_target::search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
344 const gdb_byte *pattern, ULONGEST pattern_len,
345 CORE_ADDR *found_addrp)
85e747d2 346{
f6ac5f3d 347 struct target_ops *ops_beneath = find_target_beneath (this);
85e747d2 348
e75fdfca
TT
349 /* For SPU local store, always fall back to the simple method. */
350 if (SPUADDR_SPU (start_addr) >= 0)
f6ac5f3d 351 return simple_search_memory (this, start_addr, search_space_len,
85e747d2
UW
352 pattern, pattern_len, found_addrp);
353
f6ac5f3d
PA
354 return ops_beneath->search_memory (start_addr, search_space_len,
355 pattern, pattern_len, found_addrp);
85e747d2
UW
356}
357
358
359/* Push and pop the SPU multi-architecture support target. */
360
361static void
362spu_multiarch_activate (void)
363{
364 /* If GDB was configured without SPU architecture support,
365 we cannot install SPU multi-architecture support either. */
366 if (spu_gdbarch (-1) == NULL)
367 return;
368
369 push_target (&spu_ops);
370
371 /* Make sure the thread architecture is re-evaluated. */
372 registers_changed ();
373}
374
375static void
376spu_multiarch_deactivate (void)
377{
378 unpush_target (&spu_ops);
379
380 /* Make sure the thread architecture is re-evaluated. */
381 registers_changed ();
382}
383
384static void
385spu_multiarch_inferior_created (struct target_ops *ops, int from_tty)
386{
387 if (spu_standalone_p ())
388 spu_multiarch_activate ();
389}
390
391static void
392spu_multiarch_solib_loaded (struct so_list *so)
393{
394 if (!spu_standalone_p ())
395 if (so->abfd && bfd_get_arch (so->abfd) == bfd_arch_spu)
396 if (spu_nr_solib++ == 0)
397 spu_multiarch_activate ();
398}
399
400static void
401spu_multiarch_solib_unloaded (struct so_list *so)
402{
403 if (!spu_standalone_p ())
404 if (so->abfd && bfd_get_arch (so->abfd) == bfd_arch_spu)
405 if (--spu_nr_solib == 0)
406 spu_multiarch_deactivate ();
407}
408
f6ac5f3d
PA
409void
410spu_multiarch_target::mourn_inferior ()
85e747d2 411{
f6ac5f3d 412 struct target_ops *ops_beneath = find_target_beneath (this);
85e747d2 413
f6ac5f3d 414 ops_beneath->mourn_inferior ();
85e747d2
UW
415 spu_multiarch_deactivate ();
416}
417
85e747d2
UW
418void
419_initialize_spu_multiarch (void)
420{
85e747d2 421 /* Install observers to watch for SPU objects. */
76727919
TT
422 gdb::observers::inferior_created.attach (spu_multiarch_inferior_created);
423 gdb::observers::solib_loaded.attach (spu_multiarch_solib_loaded);
424 gdb::observers::solib_unloaded.attach (spu_multiarch_solib_unloaded);
85e747d2
UW
425}
426
This page took 0.96354 seconds and 4 git commands to generate.