GDB (xrefs)
/tmp/gdb-7.10/gdb/spu-multiarch.c
Go to the documentation of this file.
1 /* Cell SPU GNU/Linux multi-architecture debugging support.
2  Copyright (C) 2009-2015 Free Software Foundation, Inc.
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
10  the Free Software Foundation; either version 3 of the License, or
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
19  along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 
21 #include "defs.h"
22 #include "gdbcore.h"
23 #include "gdbcmd.h"
24 #include "arch-utils.h"
25 #include "observer.h"
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 
37 /* This module's target vector. */
38 static struct target_ops spu_ops;
39 
40 /* Number of SPE objects loaded into the current inferior. */
41 static int spu_nr_solib;
42 
43 /* Stand-alone SPE executable? */
44 #define spu_standalone_p() \
45  (symfile_objfile && symfile_objfile->obfd \
46  && bfd_get_arch (symfile_objfile->obfd) == bfd_arch_spu)
47 
48 /* PPU side system calls. */
49 #define INSTR_SC 0x44000002
50 #define NR_spu_run 0x0116
51 
52 /* If the PPU thread is currently stopped on a spu_run system call,
53  return to FD and ADDR the file handle and NPC parameter address
54  used with the system call. Return non-zero if successful. */
55 static int
57 {
58  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
59  struct gdbarch_tdep *tdep;
60  struct regcache *regcache;
61  gdb_byte buf[4];
62  ULONGEST regval;
63 
64  /* If we're not on PPU, there's nothing to detect. */
65  if (gdbarch_bfd_arch_info (target_gdbarch ())->arch != bfd_arch_powerpc)
66  return 0;
67 
68  /* Get PPU-side registers. */
69  regcache = get_thread_arch_regcache (ptid, target_gdbarch ());
70  tdep = gdbarch_tdep (target_gdbarch ());
71 
72  /* Fetch instruction preceding current NIP. */
73  if (target_read_memory (regcache_read_pc (regcache) - 4, buf, 4) != 0)
74  return 0;
75  /* It should be a "sc" instruction. */
76  if (extract_unsigned_integer (buf, 4, byte_order) != INSTR_SC)
77  return 0;
78  /* System call number should be NR_spu_run. */
79  regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum, &regval);
80  if (regval != NR_spu_run)
81  return 0;
82 
83  /* Register 3 contains fd, register 4 the NPC param pointer. */
85  *fd = (int) regval;
86  regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum + 4, &regval);
87  *addr = (CORE_ADDR) regval;
88  return 1;
89 }
90 
91 /* Find gdbarch for SPU context SPUFS_FD. */
92 static struct gdbarch *
93 spu_gdbarch (int spufs_fd)
94 {
95  struct gdbarch_info info;
96  gdbarch_info_init (&info);
97  info.bfd_arch_info = bfd_lookup_arch (bfd_arch_spu, bfd_mach_spu);
98  info.byte_order = BFD_ENDIAN_BIG;
99  info.osabi = GDB_OSABI_LINUX;
100  info.tdep_info = (void *) &spufs_fd;
101  return gdbarch_find_by_info (info);
102 }
103 
104 /* Override the to_thread_architecture routine. */
105 static struct gdbarch *
107 {
108  int spufs_fd;
109  CORE_ADDR spufs_addr;
110 
111  if (parse_spufs_run (ptid, &spufs_fd, &spufs_addr))
112  return spu_gdbarch (spufs_fd);
113 
114  return target_gdbarch ();
115 }
116 
117 /* Override the to_region_ok_for_hw_watchpoint routine. */
118 static int
120  CORE_ADDR addr, int len)
121 {
122  struct target_ops *ops_beneath = find_target_beneath (self);
123 
124  /* We cannot watch SPU local store. */
125  if (SPUADDR_SPU (addr) != -1)
126  return 0;
127 
128  return ops_beneath->to_region_ok_for_hw_watchpoint (ops_beneath, addr, len);
129 }
130 
131 /* Override the to_fetch_registers routine. */
132 static void
134  struct regcache *regcache, int regno)
135 {
136  struct gdbarch *gdbarch = get_regcache_arch (regcache);
137  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
138  struct target_ops *ops_beneath = find_target_beneath (ops);
139  int spufs_fd;
140  CORE_ADDR spufs_addr;
141 
142  /* This version applies only if we're currently in spu_run. */
143  if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_spu)
144  {
145  ops_beneath->to_fetch_registers (ops_beneath, regcache, regno);
146  return;
147  }
148 
149  /* We must be stopped on a spu_run system call. */
150  if (!parse_spufs_run (inferior_ptid, &spufs_fd, &spufs_addr))
151  return;
152 
153  /* The ID register holds the spufs file handle. */
154  if (regno == -1 || regno == SPU_ID_REGNUM)
155  {
156  gdb_byte buf[4];
157  store_unsigned_integer (buf, 4, byte_order, spufs_fd);
158  regcache_raw_supply (regcache, SPU_ID_REGNUM, buf);
159  }
160 
161  /* The NPC register is found in PPC memory at SPUFS_ADDR. */
162  if (regno == -1 || regno == SPU_PC_REGNUM)
163  {
164  gdb_byte buf[4];
165 
166  if (target_read (ops_beneath, TARGET_OBJECT_MEMORY, NULL,
167  buf, spufs_addr, sizeof buf) == sizeof buf)
168  regcache_raw_supply (regcache, SPU_PC_REGNUM, buf);
169  }
170 
171  /* The GPRs are found in the "regs" spufs file. */
172  if (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))
173  {
174  gdb_byte buf[16 * SPU_NUM_GPRS];
175  char annex[32];
176  int i;
177 
178  xsnprintf (annex, sizeof annex, "%d/regs", spufs_fd);
179  if (target_read (ops_beneath, TARGET_OBJECT_SPU, annex,
180  buf, 0, sizeof buf) == sizeof buf)
181  for (i = 0; i < SPU_NUM_GPRS; i++)
182  regcache_raw_supply (regcache, i, buf + i*16);
183  }
184 }
185 
186 /* Override the to_store_registers routine. */
187 static void
189  struct regcache *regcache, int regno)
190 {
191  struct gdbarch *gdbarch = get_regcache_arch (regcache);
192  struct target_ops *ops_beneath = find_target_beneath (ops);
193  int spufs_fd;
194  CORE_ADDR spufs_addr;
195 
196  /* This version applies only if we're currently in spu_run. */
197  if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_spu)
198  {
199  ops_beneath->to_store_registers (ops_beneath, regcache, regno);
200  return;
201  }
202 
203  /* We must be stopped on a spu_run system call. */
204  if (!parse_spufs_run (inferior_ptid, &spufs_fd, &spufs_addr))
205  return;
206 
207  /* The NPC register is found in PPC memory at SPUFS_ADDR. */
208  if (regno == -1 || regno == SPU_PC_REGNUM)
209  {
210  gdb_byte buf[4];
211  regcache_raw_collect (regcache, SPU_PC_REGNUM, buf);
212 
213  target_write (ops_beneath, TARGET_OBJECT_MEMORY, NULL,
214  buf, spufs_addr, sizeof buf);
215  }
216 
217  /* The GPRs are found in the "regs" spufs file. */
218  if (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))
219  {
220  gdb_byte buf[16 * SPU_NUM_GPRS];
221  char annex[32];
222  int i;
223 
224  for (i = 0; i < SPU_NUM_GPRS; i++)
225  regcache_raw_collect (regcache, i, buf + i*16);
226 
227  xsnprintf (annex, sizeof annex, "%d/regs", spufs_fd);
228  target_write (ops_beneath, TARGET_OBJECT_SPU, annex,
229  buf, 0, sizeof buf);
230  }
231 }
232 
233 /* Override the to_xfer_partial routine. */
234 static enum target_xfer_status
235 spu_xfer_partial (struct target_ops *ops, enum target_object object,
236  const char *annex, gdb_byte *readbuf,
237  const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
238  ULONGEST *xfered_len)
239 {
240  struct target_ops *ops_beneath = find_target_beneath (ops);
241 
242  /* Use the "mem" spufs file to access SPU local store. */
243  if (object == TARGET_OBJECT_MEMORY)
244  {
245  int fd = SPUADDR_SPU (offset);
246  CORE_ADDR addr = SPUADDR_ADDR (offset);
247  char mem_annex[32], lslr_annex[32];
248  gdb_byte buf[32];
249  ULONGEST lslr;
250  enum target_xfer_status ret;
251 
252  if (fd >= 0)
253  {
254  xsnprintf (mem_annex, sizeof mem_annex, "%d/mem", fd);
255  ret = ops_beneath->to_xfer_partial (ops_beneath, TARGET_OBJECT_SPU,
256  mem_annex, readbuf, writebuf,
257  addr, len, xfered_len);
258  if (ret == TARGET_XFER_OK)
259  return ret;
260 
261  /* SPU local store access wraps the address around at the
262  local store limit. We emulate this here. To avoid needing
263  an extra access to retrieve the LSLR, we only do that after
264  trying the original address first, and getting end-of-file. */
265  xsnprintf (lslr_annex, sizeof lslr_annex, "%d/lslr", fd);
266  memset (buf, 0, sizeof buf);
267  if (ops_beneath->to_xfer_partial (ops_beneath, TARGET_OBJECT_SPU,
268  lslr_annex, buf, NULL,
269  0, sizeof buf, xfered_len)
270  != TARGET_XFER_OK)
271  return ret;
272 
273  lslr = strtoulst ((char *) buf, NULL, 16);
274  return ops_beneath->to_xfer_partial (ops_beneath, TARGET_OBJECT_SPU,
275  mem_annex, readbuf, writebuf,
276  addr & lslr, len, xfered_len);
277  }
278  }
279 
280  return ops_beneath->to_xfer_partial (ops_beneath, object, annex,
281  readbuf, writebuf, offset, len, xfered_len);
282 }
283 
284 /* Override the to_search_memory routine. */
285 static int
287  CORE_ADDR start_addr, ULONGEST search_space_len,
288  const gdb_byte *pattern, ULONGEST pattern_len,
289  CORE_ADDR *found_addrp)
290 {
291  struct target_ops *ops_beneath = find_target_beneath (ops);
292 
293  /* For SPU local store, always fall back to the simple method. */
294  if (SPUADDR_SPU (start_addr) >= 0)
295  return simple_search_memory (ops,
296  start_addr, search_space_len,
297  pattern, pattern_len, found_addrp);
298 
299  return ops_beneath->to_search_memory (ops_beneath,
300  start_addr, search_space_len,
301  pattern, pattern_len, found_addrp);
302 }
303 
304 
305 /* Push and pop the SPU multi-architecture support target. */
306 
307 static void
309 {
310  /* If GDB was configured without SPU architecture support,
311  we cannot install SPU multi-architecture support either. */
312  if (spu_gdbarch (-1) == NULL)
313  return;
314 
315  push_target (&spu_ops);
316 
317  /* Make sure the thread architecture is re-evaluated. */
319 }
320 
321 static void
323 {
325 
326  /* Make sure the thread architecture is re-evaluated. */
328 }
329 
330 static void
331 spu_multiarch_inferior_created (struct target_ops *ops, int from_tty)
332 {
333  if (spu_standalone_p ())
335 }
336 
337 static void
339 {
340  if (!spu_standalone_p ())
341  if (so->abfd && bfd_get_arch (so->abfd) == bfd_arch_spu)
342  if (spu_nr_solib++ == 0)
344 }
345 
346 static void
348 {
349  if (!spu_standalone_p ())
350  if (so->abfd && bfd_get_arch (so->abfd) == bfd_arch_spu)
351  if (--spu_nr_solib == 0)
353 }
354 
355 static void
357 {
358  struct target_ops *ops_beneath = find_target_beneath (ops);
359 
360  ops_beneath->to_mourn_inferior (ops_beneath);
362 }
363 
364 
365 /* Initialize the SPU multi-architecture support target. */
366 
367 static void
369 {
370  spu_ops.to_shortname = "spu";
371  spu_ops.to_longname = "SPU multi-architecture support.";
372  spu_ops.to_doc = "SPU multi-architecture support.";
382 }
383 
384 /* -Wmissing-prototypes */
386 
387 void
389 {
390  /* Install ourselves on the target stack. */
391  init_spu_ops ();
393 
394  /* Install observers to watch for SPU objects. */
398 }
399 
struct gdbarch * target_gdbarch(void)
Definition: gdbarch.c:5143
static struct gdbarch * spu_gdbarch(int spufs_fd)
Definition: spu-multiarch.c:93
ULONGEST extract_unsigned_integer(const gdb_byte *, int, enum bfd_endian)
Definition: findvar.c:84
static void spu_mourn_inferior(struct target_ops *ops)
const char * to_longname
Definition: target.h:433
bfd_vma CORE_ADDR
Definition: common-types.h:41
static int spu_nr_solib
Definition: spu-multiarch.c:41
static void spu_multiarch_solib_loaded(struct so_list *so)
struct gdbarch * get_regcache_arch(const struct regcache *regcache)
Definition: regcache.c:297
#define SPUADDR_SPU(addr)
Definition: spu-tdep.h:107
static struct gdbarch * spu_thread_architecture(struct target_ops *ops, ptid_t ptid)
LONGEST target_write(struct target_ops *ops, enum target_object object, const char *annex, const gdb_byte *buf, ULONGEST offset, LONGEST len)
Definition: target.c:1894
void push_target(struct target_ops *t)
Definition: target.c:664
int unpush_target(struct target_ops *t)
Definition: target.c:711
struct gdbarch * gdbarch_find_by_info(struct gdbarch_info info)
Definition: gdbarch.c:5008
#define NR_spu_run
Definition: spu-multiarch.c:50
Definition: solist.h:30
int(* to_region_ok_for_hw_watchpoint)(struct target_ops *, CORE_ADDR, int) TARGET_DEFAULT_FUNC(default_region_ok_for_hw_watchpoint)
Definition: target.h:554
const struct bfd_arch_info * bfd_arch_info
Definition: gdbarch.h:1549
struct gdbarch_tdep_info * tdep_info
Definition: gdbarch.h:1560
struct gdbarch_tdep * gdbarch_tdep(struct gdbarch *gdbarch)
Definition: gdbarch.c:1402
static struct target_ops spu_ops
Definition: spu-multiarch.c:38
void store_unsigned_integer(gdb_byte *, int, enum bfd_endian, ULONGEST)
Definition: findvar.c:212
Definition: ptid.h:35
bfd * abfd
Definition: solist.h:63
static void spu_multiarch_solib_unloaded(struct so_list *so)
static void spu_store_registers(struct target_ops *ops, struct regcache *regcache, int regno)
struct observer * observer_attach_inferior_created(observer_inferior_created_ftype *f)
#define OPS_MAGIC
Definition: target.h:1233
static void spu_multiarch_deactivate(void)
void initialize_file_ftype(void)
Definition: defs.h:281
void complete_target_initialization(struct target_ops *t)
Definition: target.c:317
enum register_status regcache_cooked_read_unsigned(struct regcache *regcache, int regnum, ULONGEST *val)
Definition: regcache.c:837
int ppc_gp0_regnum
Definition: ppc-tdep.h:214
struct observer * observer_attach_solib_unloaded(observer_solib_unloaded_ftype *f)
enum bfd_endian gdbarch_byte_order(struct gdbarch *gdbarch)
Definition: gdbarch.c:1420
target_xfer_status
Definition: target.h:219
enum gdb_osabi osabi
Definition: gdbarch.h:1563
#define SPU_NUM_GPRS
Definition: spu-tdep.h:25
const char * to_doc
Definition: target.h:434
initialize_file_ftype _initialize_spu_multiarch
static int parse_spufs_run(ptid_t ptid, int *fd, CORE_ADDR *addr)
Definition: spu-multiarch.c:56
enum target_xfer_status(* to_xfer_partial)(struct target_ops *ops, enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) TARGET_DEFAULT_RETURN(TARGET_XFER_E_IO)
Definition: target.h:724
ULONGEST strtoulst(const char *num, const char **trailer, int base)
Definition: common-utils.c:188
int(* to_search_memory)(struct target_ops *ops, CORE_ADDR start_addr, ULONGEST search_space_len, const gdb_byte *pattern, ULONGEST pattern_len, CORE_ADDR *found_addrp) TARGET_DEFAULT_FUNC(default_search_memory)
Definition: target.h:794
struct target_ops * find_target_beneath(struct target_ops *t)
Definition: target.c:3148
static void spu_fetch_registers(struct target_ops *ops, struct regcache *regcache, int regno)
target_object
Definition: target.h:136
#define spu_standalone_p()
Definition: spu-multiarch.c:44
static enum target_xfer_status spu_xfer_partial(struct target_ops *ops, enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
const char const char int
Definition: command.h:229
bfd_byte gdb_byte
Definition: common-types.h:38
int simple_search_memory(struct target_ops *ops, CORE_ADDR start_addr, ULONGEST search_space_len, const gdb_byte *pattern, ULONGEST pattern_len, CORE_ADDR *found_addrp)
Definition: target.c:2324
void(* to_fetch_registers)(struct target_ops *, struct regcache *, int) TARGET_DEFAULT_IGNORE()
Definition: target.h:472
void(* to_mourn_inferior)(struct target_ops *) TARGET_DEFAULT_FUNC(default_mourn_inferior)
Definition: target.h:607
int xsnprintf(char *str, size_t size, const char *format,...)
Definition: common-utils.c:134
int target_read_memory(CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
Definition: target.c:1393
void gdbarch_info_init(struct gdbarch_info *info)
Definition: arch-utils.c:708
static void init_spu_ops(void)
CORE_ADDR regcache_read_pc(struct regcache *regcache)
Definition: regcache.c:1174
ptid_t inferior_ptid
Definition: infcmd.c:124
enum strata to_stratum
Definition: target.h:650
int offset
Definition: agent.c:65
void registers_changed(void)
Definition: regcache.c:624
struct gdbarch *(* to_thread_architecture)(struct target_ops *, ptid_t) TARGET_DEFAULT_FUNC(default_thread_architecture)
Definition: target.h:847
void regcache_raw_supply(struct regcache *regcache, int regnum, const void *buf)
Definition: regcache.c:1041
const char * to_shortname
Definition: target.h:432
unsigned long long ULONGEST
Definition: common-types.h:53
int to_magic
Definition: target.h:1224
LONGEST target_read(struct target_ops *ops, enum target_object object, const char *annex, gdb_byte *buf, ULONGEST offset, LONGEST len)
Definition: target.c:1590
const struct bfd_arch_info * gdbarch_bfd_arch_info(struct gdbarch *gdbarch)
Definition: gdbarch.c:1411
void regcache_raw_collect(const struct regcache *regcache, int regnum, void *buf)
Definition: regcache.c:1071
static int spu_region_ok_for_hw_watchpoint(struct target_ops *self, CORE_ADDR addr, int len)
enum bfd_endian byte_order
Definition: gdbarch.h:1552
void(* to_store_registers)(struct target_ops *, struct regcache *, int) TARGET_DEFAULT_NORETURN(noprocess())
Definition: target.h:474
#define INSTR_SC
Definition: spu-multiarch.c:49
enum bfd_endian byte_order
Definition: gdbarch.c:128
static void spu_multiarch_activate(void)
#define SPUADDR_ADDR(addr)
Definition: spu-tdep.h:112
struct observer * observer_attach_solib_loaded(observer_solib_loaded_ftype *f)
struct regcache * get_thread_arch_regcache(ptid_t ptid, struct gdbarch *gdbarch)
Definition: regcache.c:508
static int spu_search_memory(struct target_ops *ops, CORE_ADDR start_addr, ULONGEST search_space_len, const gdb_byte *pattern, ULONGEST pattern_len, CORE_ADDR *found_addrp)
const ULONGEST const LONGEST len
Definition: target.h:309
static void spu_multiarch_inferior_created(struct target_ops *ops, int from_tty)