OSDN Git Service

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