OSDN Git Service

PR 11123
[pf3gnuchains/pf3gnuchains3x.git] / gdb / spu-multiarch.c
1 /* Cell SPU GNU/Linux multi-architecture debugging support.
2    Copyright (C) 2009, 2010 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 "gdb_string.h"
25 #include "gdb_assert.h"
26 #include "arch-utils.h"
27 #include "observer.h"
28 #include "inferior.h"
29 #include "regcache.h"
30 #include "symfile.h"
31 #include "objfiles.h"
32 #include "solib.h"
33 #include "solist.h"
34
35 #include "ppc-tdep.h"
36 #include "ppc-linux-tdep.h"
37 #include "spu-tdep.h"
38
39 /* This module's target vector.  */
40 static struct target_ops spu_ops;
41
42 /* Number of SPE objects loaded into the current inferior.  */
43 static int spu_nr_solib;
44
45 /* Stand-alone SPE executable?  */
46 #define spu_standalone_p() \
47   (symfile_objfile && symfile_objfile->obfd \
48    && bfd_get_arch (symfile_objfile->obfd) == bfd_arch_spu)
49
50 /* PPU side system calls.  */
51 #define INSTR_SC        0x44000002
52 #define NR_spu_run      0x0116
53
54 /* If the PPU thread is currently stopped on a spu_run system call,
55    return to FD and ADDR the file handle and NPC parameter address
56    used with the system call.  Return non-zero if successful.  */
57 static int
58 parse_spufs_run (ptid_t ptid, int *fd, CORE_ADDR *addr)
59 {
60   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
61   struct gdbarch_tdep *tdep;
62   struct regcache *regcache;
63   char buf[4];
64   CORE_ADDR pc;
65   ULONGEST regval;
66
67   /* If we're not on PPU, there's nothing to detect.  */
68   if (gdbarch_bfd_arch_info (target_gdbarch)->arch != bfd_arch_powerpc)
69     return 0;
70
71   /* Get PPU-side registers.  */
72   regcache = get_thread_arch_regcache (ptid, target_gdbarch);
73   tdep = gdbarch_tdep (target_gdbarch);
74
75   /* Fetch instruction preceding current NIP.  */
76   if (target_read_memory (regcache_read_pc (regcache) - 4, buf, 4) != 0)
77     return 0;
78   /* It should be a "sc" instruction.  */
79   if (extract_unsigned_integer (buf, 4, byte_order) != INSTR_SC)
80     return 0;
81   /* System call number should be NR_spu_run.  */
82   regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum, &regval);
83   if (regval != NR_spu_run)
84     return 0;
85
86   /* Register 3 contains fd, register 4 the NPC param pointer.  */
87   regcache_cooked_read_unsigned (regcache, PPC_ORIG_R3_REGNUM, &regval);
88   *fd = (int) regval;
89   regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum + 4, &regval);
90   *addr = (CORE_ADDR) regval;
91   return 1;
92 }
93
94 /* Find gdbarch for SPU context SPUFS_FD.  */
95 static struct gdbarch *
96 spu_gdbarch (int spufs_fd)
97 {
98   struct gdbarch_info info;
99   gdbarch_info_init (&info);
100   info.bfd_arch_info = bfd_lookup_arch (bfd_arch_spu, bfd_mach_spu);
101   info.byte_order = BFD_ENDIAN_BIG;
102   info.osabi = GDB_OSABI_LINUX;
103   info.tdep_info = (void *) &spufs_fd;
104   return gdbarch_find_by_info (info);
105 }
106
107 /* Override the to_thread_architecture routine.  */
108 static struct gdbarch *
109 spu_thread_architecture (struct target_ops *ops, ptid_t ptid)
110 {
111   int spufs_fd;
112   CORE_ADDR spufs_addr;
113
114   if (parse_spufs_run (ptid, &spufs_fd, &spufs_addr))
115     return spu_gdbarch (spufs_fd);
116
117   return target_gdbarch;
118 }
119
120 /* Override the to_region_ok_for_hw_watchpoint routine.  */
121 static int
122 spu_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
123 {
124   struct target_ops *ops_beneath = find_target_beneath (&spu_ops);
125   while (ops_beneath && !ops_beneath->to_region_ok_for_hw_watchpoint)
126     ops_beneath = find_target_beneath (ops_beneath);
127
128   /* We cannot watch SPU local store.  */
129   if (SPUADDR_SPU (addr) != -1)
130     return 0;
131
132   if (ops_beneath)
133     return ops_beneath->to_region_ok_for_hw_watchpoint (addr, len);
134
135   return 0;
136 }
137
138 /* Override the to_fetch_registers routine.  */
139 static void
140 spu_fetch_registers (struct target_ops *ops,
141                      struct regcache *regcache, int regno)
142 {
143   struct gdbarch *gdbarch = get_regcache_arch (regcache);
144   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
145   struct target_ops *ops_beneath = find_target_beneath (ops);
146   int spufs_fd;
147   CORE_ADDR spufs_addr;
148
149   /* This version applies only if we're currently in spu_run.  */
150   if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_spu)
151     {
152       while (ops_beneath && !ops_beneath->to_fetch_registers)
153         ops_beneath = find_target_beneath (ops_beneath);
154
155       gdb_assert (ops_beneath);
156       ops_beneath->to_fetch_registers (ops_beneath, regcache, regno);
157       return;
158     }
159
160   /* We must be stopped on a spu_run system call.  */
161   if (!parse_spufs_run (inferior_ptid, &spufs_fd, &spufs_addr))
162     return;
163
164   /* The ID register holds the spufs file handle.  */
165   if (regno == -1 || regno == SPU_ID_REGNUM)
166     {
167       char buf[4];
168       store_unsigned_integer (buf, 4, byte_order, spufs_fd);
169       regcache_raw_supply (regcache, SPU_ID_REGNUM, buf);
170     }
171
172   /* The NPC register is found in PPC memory at SPUFS_ADDR.  */
173   if (regno == -1 || regno == SPU_PC_REGNUM)
174     {
175       char buf[4];
176
177       if (target_read (ops_beneath, TARGET_OBJECT_MEMORY, NULL,
178                        buf, spufs_addr, sizeof buf) == sizeof buf)
179         regcache_raw_supply (regcache, SPU_PC_REGNUM, buf);
180     }
181
182   /* The GPRs are found in the "regs" spufs file.  */
183   if (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))
184     {
185       char buf[16 * SPU_NUM_GPRS], annex[32];
186       int i;
187
188       xsnprintf (annex, sizeof annex, "%d/regs", spufs_fd);
189       if (target_read (ops_beneath, TARGET_OBJECT_SPU, annex,
190                        buf, 0, sizeof buf) == sizeof buf)
191         for (i = 0; i < SPU_NUM_GPRS; i++)
192           regcache_raw_supply (regcache, i, buf + i*16);
193     }
194 }
195
196 /* Override the to_store_registers routine.  */
197 static void
198 spu_store_registers (struct target_ops *ops,
199                      struct regcache *regcache, int regno)
200 {
201   struct gdbarch *gdbarch = get_regcache_arch (regcache);
202   struct target_ops *ops_beneath = find_target_beneath (ops);
203   int spufs_fd;
204   CORE_ADDR spufs_addr;
205
206   /* This version applies only if we're currently in spu_run.  */
207   if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_spu)
208     {
209       while (ops_beneath && !ops_beneath->to_fetch_registers)
210         ops_beneath = find_target_beneath (ops_beneath);
211
212       gdb_assert (ops_beneath);
213       ops_beneath->to_store_registers (ops_beneath, regcache, regno);
214       return;
215     }
216
217   /* We must be stopped on a spu_run system call.  */
218   if (!parse_spufs_run (inferior_ptid, &spufs_fd, &spufs_addr))
219     return;
220
221   /* The NPC register is found in PPC memory at SPUFS_ADDR.  */
222   if (regno == -1 || regno == SPU_PC_REGNUM)
223     {
224       char buf[4];
225       regcache_raw_collect (regcache, SPU_PC_REGNUM, buf);
226
227       target_write (ops_beneath, TARGET_OBJECT_MEMORY, NULL,
228                     buf, spufs_addr, sizeof buf);
229     }
230
231   /* The GPRs are found in the "regs" spufs file.  */
232   if (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))
233     {
234       char buf[16 * SPU_NUM_GPRS], annex[32];
235       int i;
236
237       for (i = 0; i < SPU_NUM_GPRS; i++)
238         regcache_raw_collect (regcache, i, buf + i*16);
239
240       xsnprintf (annex, sizeof annex, "%d/regs", spufs_fd);
241       target_write (ops_beneath, TARGET_OBJECT_SPU, annex,
242                     buf, 0, sizeof buf);
243     }
244 }
245
246 /* Override the to_xfer_partial routine.  */
247 static LONGEST
248 spu_xfer_partial (struct target_ops *ops, enum target_object object,
249                   const char *annex, gdb_byte *readbuf,
250                   const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
251 {
252   struct target_ops *ops_beneath = find_target_beneath (ops);
253   while (ops_beneath && !ops_beneath->to_xfer_partial)
254     ops_beneath = find_target_beneath (ops_beneath);
255   gdb_assert (ops_beneath);
256
257   /* Use the "mem" spufs file to access SPU local store.  */
258   if (object == TARGET_OBJECT_MEMORY)
259     {
260       int fd = SPUADDR_SPU (offset);
261       CORE_ADDR addr = SPUADDR_ADDR (offset);
262       char mem_annex[32];
263
264       if (fd >= 0 && addr < SPU_LS_SIZE)
265         {
266           xsnprintf (mem_annex, sizeof mem_annex, "%d/mem", fd);
267           return ops_beneath->to_xfer_partial (ops_beneath, TARGET_OBJECT_SPU,
268                                                mem_annex, readbuf, writebuf,
269                                                addr, len);
270         }
271     }
272
273   return ops_beneath->to_xfer_partial (ops_beneath, object, annex,
274                                        readbuf, writebuf, offset, len);
275 }
276
277 /* Override the to_search_memory routine.  */
278 static int
279 spu_search_memory (struct target_ops* ops,
280                    CORE_ADDR start_addr, ULONGEST search_space_len,
281                    const gdb_byte *pattern, ULONGEST pattern_len,
282                    CORE_ADDR *found_addrp)
283 {
284   struct target_ops *ops_beneath = find_target_beneath (ops);
285   while (ops_beneath && !ops_beneath->to_search_memory)
286     ops_beneath = find_target_beneath (ops_beneath);
287
288   /* For SPU local store, always fall back to the simple method.  Likewise
289      if we do not have any target-specific special implementation.  */
290   if (!ops_beneath || SPUADDR_SPU (start_addr) >= 0)
291     return simple_search_memory (ops,
292                                  start_addr, search_space_len,
293                                  pattern, pattern_len, found_addrp);
294
295   return ops_beneath->to_search_memory (ops_beneath,
296                                         start_addr, search_space_len,
297                                         pattern, pattern_len, found_addrp);
298 }
299
300
301 /* Push and pop the SPU multi-architecture support target.  */
302
303 static void
304 spu_multiarch_activate (void)
305 {
306   /* If GDB was configured without SPU architecture support,
307      we cannot install SPU multi-architecture support either.  */
308   if (spu_gdbarch (-1) == NULL)
309     return;
310
311   push_target (&spu_ops);
312
313   /* Make sure the thread architecture is re-evaluated.  */
314   registers_changed ();
315 }
316
317 static void
318 spu_multiarch_deactivate (void)
319 {
320   unpush_target (&spu_ops);
321
322   /* Make sure the thread architecture is re-evaluated.  */
323   registers_changed ();
324 }
325
326 static void
327 spu_multiarch_inferior_created (struct target_ops *ops, int from_tty)
328 {
329   if (spu_standalone_p ())
330     spu_multiarch_activate ();
331 }
332
333 static void
334 spu_multiarch_solib_loaded (struct so_list *so)
335 {
336   if (!spu_standalone_p ())
337     if (so->abfd && bfd_get_arch (so->abfd) == bfd_arch_spu)
338       if (spu_nr_solib++ == 0)
339         spu_multiarch_activate ();
340 }
341
342 static void
343 spu_multiarch_solib_unloaded (struct so_list *so)
344 {
345   if (!spu_standalone_p ())
346     if (so->abfd && bfd_get_arch (so->abfd) == bfd_arch_spu)
347       if (--spu_nr_solib == 0)
348         spu_multiarch_deactivate ();
349 }
350
351 static void
352 spu_mourn_inferior (struct target_ops *ops)
353 {
354   struct target_ops *ops_beneath = find_target_beneath (ops);
355   while (ops_beneath && !ops_beneath->to_mourn_inferior)
356     ops_beneath = find_target_beneath (ops_beneath);
357
358   gdb_assert (ops_beneath);
359   ops_beneath->to_mourn_inferior (ops_beneath);
360   spu_multiarch_deactivate ();
361 }
362
363
364 /* Initialize the SPU multi-architecture support target.  */
365
366 static void
367 init_spu_ops (void)
368 {
369   spu_ops.to_shortname = "spu";
370   spu_ops.to_longname = "SPU multi-architecture support.";
371   spu_ops.to_doc = "SPU multi-architecture support.";
372   spu_ops.to_mourn_inferior = spu_mourn_inferior;
373   spu_ops.to_fetch_registers = spu_fetch_registers;
374   spu_ops.to_store_registers = spu_store_registers;
375   spu_ops.to_xfer_partial = spu_xfer_partial;
376   spu_ops.to_search_memory = spu_search_memory;
377   spu_ops.to_region_ok_for_hw_watchpoint = spu_region_ok_for_hw_watchpoint;
378   spu_ops.to_thread_architecture = spu_thread_architecture;
379   spu_ops.to_stratum = arch_stratum;
380   spu_ops.to_magic = OPS_MAGIC;
381 }
382
383 void
384 _initialize_spu_multiarch (void)
385 {
386   /* Install ourselves on the target stack.  */
387   init_spu_ops ();
388   add_target (&spu_ops);
389
390   /* Install observers to watch for SPU objects.  */
391   observer_attach_inferior_created (spu_multiarch_inferior_created);
392   observer_attach_solib_loaded (spu_multiarch_solib_loaded);
393   observer_attach_solib_unloaded (spu_multiarch_solib_unloaded);
394 }
395