GDB (xrefs)
/tmp/gdb-8.1/gdb/spu-multiarch.c
Go to the documentation of this file.
1 /* Cell SPU GNU/Linux multi-architecture debugging support.
2  Copyright (C) 2009-2018 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
56 parse_spufs_run (ptid_t ptid, int *fd, CORE_ADDR *addr)
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  /* If we're called too early (e.g. after fork), we cannot
69  access the inferior yet. */
70  if (find_inferior_ptid (ptid) == NULL)
71  return 0;
72 
73  /* Get PPU-side registers. */
75  tdep = gdbarch_tdep (target_gdbarch ());
76 
77  /* Fetch instruction preceding current NIP. */
78  {
79  scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
81  regval = target_read_memory (regcache_read_pc (regcache) - 4, buf, 4);
82  }
83  if (regval != 0)
84  return 0;
85  /* It should be a "sc" instruction. */
86  if (extract_unsigned_integer (buf, 4, byte_order) != INSTR_SC)
87  return 0;
88  /* System call number should be NR_spu_run. */
90  if (regval != NR_spu_run)
91  return 0;
92 
93  /* Register 3 contains fd, register 4 the NPC param pointer. */
95  *fd = (int) regval;
97  *addr = (CORE_ADDR) regval;
98  return 1;
99 }
100 
101 /* Find gdbarch for SPU context SPUFS_FD. */
102 static struct gdbarch *
103 spu_gdbarch (int spufs_fd)
104 {
105  struct gdbarch_info info;
106  gdbarch_info_init (&info);
107  info.bfd_arch_info = bfd_lookup_arch (bfd_arch_spu, bfd_mach_spu);
108  info.byte_order = BFD_ENDIAN_BIG;
109  info.osabi = GDB_OSABI_LINUX;
110  info.id = &spufs_fd;
111  return gdbarch_find_by_info (info);
112 }
113 
114 /* Override the to_thread_architecture routine. */
115 static struct gdbarch *
117 {
118  int spufs_fd;
119  CORE_ADDR spufs_addr;
120 
121  if (parse_spufs_run (ptid, &spufs_fd, &spufs_addr))
122  return spu_gdbarch (spufs_fd);
123 
124  target_ops *beneath = find_target_beneath (ops);
125  return beneath->to_thread_architecture (beneath, ptid);
126 }
127 
128 /* Override the to_region_ok_for_hw_watchpoint routine. */
129 static int
131  CORE_ADDR addr, int len)
132 {
133  struct target_ops *ops_beneath = find_target_beneath (self);
134 
135  /* We cannot watch SPU local store. */
136  if (SPUADDR_SPU (addr) != -1)
137  return 0;
138 
139  return ops_beneath->to_region_ok_for_hw_watchpoint (ops_beneath, addr, len);
140 }
141 
142 /* Override the to_fetch_registers routine. */
143 static void
145  struct regcache *regcache, int regno)
146 {
147  struct gdbarch *gdbarch = regcache->arch ();
148  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
149  struct target_ops *ops_beneath = find_target_beneath (ops);
150  int spufs_fd;
151  CORE_ADDR spufs_addr;
152 
153  /* Since we use functions that rely on inferior_ptid, we need to set and
154  restore it. */
155  scoped_restore save_ptid
157 
158  /* This version applies only if we're currently in spu_run. */
159  if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_spu)
160  {
161  ops_beneath->to_fetch_registers (ops_beneath, regcache, regno);
162  return;
163  }
164 
165  /* We must be stopped on a spu_run system call. */
166  if (!parse_spufs_run (inferior_ptid, &spufs_fd, &spufs_addr))
167  return;
168 
169  /* The ID register holds the spufs file handle. */
170  if (regno == -1 || regno == SPU_ID_REGNUM)
171  {
172  gdb_byte buf[4];
173  store_unsigned_integer (buf, 4, byte_order, spufs_fd);
175  }
176 
177  /* The NPC register is found in PPC memory at SPUFS_ADDR. */
178  if (regno == -1 || regno == SPU_PC_REGNUM)
179  {
180  gdb_byte buf[4];
181 
182  if (target_read (ops_beneath, TARGET_OBJECT_MEMORY, NULL,
183  buf, spufs_addr, sizeof buf) == sizeof buf)
185  }
186 
187  /* The GPRs are found in the "regs" spufs file. */
188  if (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))
189  {
190  gdb_byte buf[16 * SPU_NUM_GPRS];
191  char annex[32];
192  int i;
193 
194  xsnprintf (annex, sizeof annex, "%d/regs", spufs_fd);
195  if (target_read (ops_beneath, TARGET_OBJECT_SPU, annex,
196  buf, 0, sizeof buf) == sizeof buf)
197  for (i = 0; i < SPU_NUM_GPRS; i++)
198  regcache_raw_supply (regcache, i, buf + i*16);
199  }
200 }
201 
202 /* Override the to_store_registers routine. */
203 static void
205  struct regcache *regcache, int regno)
206 {
207  struct gdbarch *gdbarch = regcache->arch ();
208  struct target_ops *ops_beneath = find_target_beneath (ops);
209  int spufs_fd;
210  CORE_ADDR spufs_addr;
211 
212  /* Since we use functions that rely on inferior_ptid, we need to set and
213  restore it. */
214  scoped_restore save_ptid
216 
217  /* This version applies only if we're currently in spu_run. */
218  if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_spu)
219  {
220  ops_beneath->to_store_registers (ops_beneath, regcache, regno);
221  return;
222  }
223 
224  /* We must be stopped on a spu_run system call. */
225  if (!parse_spufs_run (inferior_ptid, &spufs_fd, &spufs_addr))
226  return;
227 
228  /* The NPC register is found in PPC memory at SPUFS_ADDR. */
229  if (regno == -1 || regno == SPU_PC_REGNUM)
230  {
231  gdb_byte buf[4];
233 
234  target_write (ops_beneath, TARGET_OBJECT_MEMORY, NULL,
235  buf, spufs_addr, sizeof buf);
236  }
237 
238  /* The GPRs are found in the "regs" spufs file. */
239  if (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))
240  {
241  gdb_byte buf[16 * SPU_NUM_GPRS];
242  char annex[32];
243  int i;
244 
245  for (i = 0; i < SPU_NUM_GPRS; i++)
246  regcache_raw_collect (regcache, i, buf + i*16);
247 
248  xsnprintf (annex, sizeof annex, "%d/regs", spufs_fd);
249  target_write (ops_beneath, TARGET_OBJECT_SPU, annex,
250  buf, 0, sizeof buf);
251  }
252 }
253 
254 /* Override the to_xfer_partial routine. */
255 static enum target_xfer_status
256 spu_xfer_partial (struct target_ops *ops, enum target_object object,
257  const char *annex, gdb_byte *readbuf,
258  const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
259  ULONGEST *xfered_len)
260 {
261  struct target_ops *ops_beneath = find_target_beneath (ops);
262 
263  /* Use the "mem" spufs file to access SPU local store. */
264  if (object == TARGET_OBJECT_MEMORY)
265  {
266  int fd = SPUADDR_SPU (offset);
267  CORE_ADDR addr = SPUADDR_ADDR (offset);
268  char mem_annex[32], lslr_annex[32];
269  gdb_byte buf[32];
270  ULONGEST lslr;
271  enum target_xfer_status ret;
272 
273  if (fd >= 0)
274  {
275  xsnprintf (mem_annex, sizeof mem_annex, "%d/mem", fd);
276  ret = ops_beneath->to_xfer_partial (ops_beneath, TARGET_OBJECT_SPU,
277  mem_annex, readbuf, writebuf,
278  addr, len, xfered_len);
279  if (ret == TARGET_XFER_OK)
280  return ret;
281 
282  /* SPU local store access wraps the address around at the
283  local store limit. We emulate this here. To avoid needing
284  an extra access to retrieve the LSLR, we only do that after
285  trying the original address first, and getting end-of-file. */
286  xsnprintf (lslr_annex, sizeof lslr_annex, "%d/lslr", fd);
287  memset (buf, 0, sizeof buf);
288  if (ops_beneath->to_xfer_partial (ops_beneath, TARGET_OBJECT_SPU,
289  lslr_annex, buf, NULL,
290  0, sizeof buf, xfered_len)
291  != TARGET_XFER_OK)
292  return ret;
293 
294  lslr = strtoulst ((char *) buf, NULL, 16);
295  return ops_beneath->to_xfer_partial (ops_beneath, TARGET_OBJECT_SPU,
296  mem_annex, readbuf, writebuf,
297  addr & lslr, len, xfered_len);
298  }
299  }
300 
301  return ops_beneath->to_xfer_partial (ops_beneath, object, annex,
302  readbuf, writebuf, offset, len, xfered_len);
303 }
304 
305 /* Override the to_search_memory routine. */
306 static int
308  CORE_ADDR start_addr, ULONGEST search_space_len,
309  const gdb_byte *pattern, ULONGEST pattern_len,
310  CORE_ADDR *found_addrp)
311 {
312  struct target_ops *ops_beneath = find_target_beneath (ops);
313 
314  /* For SPU local store, always fall back to the simple method. */
315  if (SPUADDR_SPU (start_addr) >= 0)
316  return simple_search_memory (ops,
317  start_addr, search_space_len,
318  pattern, pattern_len, found_addrp);
319 
320  return ops_beneath->to_search_memory (ops_beneath,
321  start_addr, search_space_len,
322  pattern, pattern_len, found_addrp);
323 }
324 
325 
326 /* Push and pop the SPU multi-architecture support target. */
327 
328 static void
330 {
331  /* If GDB was configured without SPU architecture support,
332  we cannot install SPU multi-architecture support either. */
333  if (spu_gdbarch (-1) == NULL)
334  return;
335 
336  push_target (&spu_ops);
337 
338  /* Make sure the thread architecture is re-evaluated. */
340 }
341 
342 static void
344 {
346 
347  /* Make sure the thread architecture is re-evaluated. */
349 }
350 
351 static void
352 spu_multiarch_inferior_created (struct target_ops *ops, int from_tty)
353 {
354  if (spu_standalone_p ())
356 }
357 
358 static void
360 {
361  if (!spu_standalone_p ())
362  if (so->abfd && bfd_get_arch (so->abfd) == bfd_arch_spu)
363  if (spu_nr_solib++ == 0)
365 }
366 
367 static void
369 {
370  if (!spu_standalone_p ())
371  if (so->abfd && bfd_get_arch (so->abfd) == bfd_arch_spu)
372  if (--spu_nr_solib == 0)
374 }
375 
376 static void
378 {
379  struct target_ops *ops_beneath = find_target_beneath (ops);
380 
381  ops_beneath->to_mourn_inferior (ops_beneath);
383 }
384 
385 
386 /* Initialize the SPU multi-architecture support target. */
387 
388 static void
390 {
391  spu_ops.to_shortname = "spu";
392  spu_ops.to_longname = "SPU multi-architecture support.";
393  spu_ops.to_doc = "SPU multi-architecture support.";
403 }
404 
405 void
407 {
408  /* Install ourselves on the target stack. */
409  init_spu_ops ();
411 
412  /* Install observers to watch for SPU objects. */
416 }
417 
struct gdbarch * target_gdbarch(void)
Definition: gdbarch.c:5467
static struct gdbarch * spu_gdbarch(int spufs_fd)
int * id
Definition: gdbarch.h:1653
static void spu_mourn_inferior(struct target_ops *ops)
const char * to_longname
Definition: target.h:416
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)
regcache(gdbarch *gdbarch)
Definition: regcache.h:235
#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:1841
void push_target(struct target_ops *t)
Definition: target.c:642
ptid_t regcache_get_ptid(const struct regcache *regcache)
Definition: regcache.c:229
int unpush_target(struct target_ops *t)
Definition: target.c:689
struct gdbarch * gdbarch_find_by_info(struct gdbarch_info info)
Definition: gdbarch.c:5332
void * memset(T *s, int c, size_t n)=delete
#define NR_spu_run
Definition: spu-multiarch.c:50
Definition: solist.h:38
struct inferior * find_inferior_ptid(ptid_t ptid)
Definition: inferior.c:321
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:543
const struct bfd_arch_info * bfd_arch_info
Definition: gdbarch.h:1629
struct gdbarch_tdep * gdbarch_tdep(struct gdbarch *gdbarch)
Definition: gdbarch.c:1491
static struct target_ops spu_ops
Definition: spu-multiarch.c:38
bfd * abfd
Definition: solist.h:71
static void spu_multiarch_solib_unloaded(struct so_list *so)
scoped_restore_tmpl< T > make_scoped_restore(T *var)
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:1270
static void spu_multiarch_deactivate(void)
void complete_target_initialization(struct target_ops *t)
Definition: target.c:317
static ULONGEST extract_unsigned_integer(const gdb_byte *addr, int len, enum bfd_endian byte_order)
Definition: defs.h:577
enum register_status regcache_cooked_read_unsigned(struct regcache *regcache, int regnum, ULONGEST *val)
Definition: regcache.c:777
Definition: ptid.h:35
int ppc_gp0_regnum
Definition: ppc-tdep.h:227
struct observer * observer_attach_solib_unloaded(observer_solib_unloaded_ftype *f)
enum bfd_endian gdbarch_byte_order(struct gdbarch *gdbarch)
Definition: gdbarch.c:1509
target_xfer_status
Definition: target.h:206
enum gdb_osabi osabi
Definition: gdbarch.h:1657
#define SPU_NUM_GPRS
Definition: spu-tdep.h:25
const char * to_doc
Definition: target.h:417
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:739
ULONGEST strtoulst(const char *num, const char **trailer, int base)
Definition: common-utils.c:266
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:815
struct target_ops * find_target_beneath(struct target_ops *t)
Definition: target.c:3153
static void spu_fetch_registers(struct target_ops *ops, struct regcache *regcache, int regno)
target_object
Definition: target.h:132
#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)
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:2323
void(* to_fetch_registers)(struct target_ops *, struct regcache *, int) TARGET_DEFAULT_IGNORE()
Definition: target.h:457
void(* to_mourn_inferior)(struct target_ops *) TARGET_DEFAULT_FUNC(default_mourn_inferior)
Definition: target.h:606
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:1370
void gdbarch_info_init(struct gdbarch_info *info)
Definition: arch-utils.c:725
static void init_spu_ops(void)
CORE_ADDR regcache_read_pc(struct regcache *regcache)
Definition: regcache.c:1229
ptid_t inferior_ptid
Definition: infcmd.c:94
enum strata to_stratum
Definition: target.h:656
int offset
Definition: agent.c:65
void registers_changed(void)
Definition: regcache.c:522
gdbarch * arch() const
Definition: regcache.c:221
struct gdbarch *(* to_thread_architecture)(struct target_ops *, ptid_t) TARGET_DEFAULT_FUNC(default_thread_architecture)
Definition: target.h:868
void regcache_raw_supply(struct regcache *regcache, int regnum, const void *buf)
Definition: regcache.c:1004
const char * to_shortname
Definition: target.h:415
unsigned long long ULONGEST
Definition: common-types.h:53
int to_magic
Definition: target.h:1261
LONGEST target_read(struct target_ops *ops, enum target_object object, const char *annex, gdb_byte *buf, ULONGEST offset, LONGEST len)
Definition: target.c:1562
const struct bfd_arch_info * gdbarch_bfd_arch_info(struct gdbarch *gdbarch)
Definition: gdbarch.c:1500
void regcache_raw_collect(const struct regcache *regcache, int regnum, void *buf)
Definition: regcache.c:1085
static int spu_region_ok_for_hw_watchpoint(struct target_ops *self, CORE_ADDR addr, int len)
ptid_t ptid() const
Definition: regcache.h:325
enum bfd_endian byte_order
Definition: gdbarch.h:1632
void(* to_store_registers)(struct target_ops *, struct regcache *, int) TARGET_DEFAULT_NORETURN(noprocess())
Definition: target.h:459
#define INSTR_SC
Definition: spu-multiarch.c:49
enum bfd_endian byte_order
Definition: gdbarch.c:137
static void spu_multiarch_activate(void)
void _initialize_spu_multiarch(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:423
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)
static void store_unsigned_integer(gdb_byte *addr, int len, enum bfd_endian byte_order, ULONGEST val)
Definition: defs.h:604
static void spu_multiarch_inferior_created(struct target_ops *ops, int from_tty)