GDB (API)
/home/stan/gdb/src/gdb/spu-multiarch.c
Go to the documentation of this file.
00001 /* Cell SPU GNU/Linux multi-architecture debugging support.
00002    Copyright (C) 2009-2013 Free Software Foundation, Inc.
00003 
00004    Contributed by Ulrich Weigand <uweigand@de.ibm.com>.
00005 
00006    This file is part of GDB.
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 3 of the License, or
00011    (at your option) any later version.
00012 
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00020 
00021 #include "defs.h"
00022 #include "gdbcore.h"
00023 #include "gdbcmd.h"
00024 #include "gdb_string.h"
00025 #include "gdb_assert.h"
00026 #include "arch-utils.h"
00027 #include "observer.h"
00028 #include "inferior.h"
00029 #include "regcache.h"
00030 #include "symfile.h"
00031 #include "objfiles.h"
00032 #include "solib.h"
00033 #include "solist.h"
00034 
00035 #include "ppc-tdep.h"
00036 #include "ppc-linux-tdep.h"
00037 #include "spu-tdep.h"
00038 
00039 /* This module's target vector.  */
00040 static struct target_ops spu_ops;
00041 
00042 /* Number of SPE objects loaded into the current inferior.  */
00043 static int spu_nr_solib;
00044 
00045 /* Stand-alone SPE executable?  */
00046 #define spu_standalone_p() \
00047   (symfile_objfile && symfile_objfile->obfd \
00048    && bfd_get_arch (symfile_objfile->obfd) == bfd_arch_spu)
00049 
00050 /* PPU side system calls.  */
00051 #define INSTR_SC        0x44000002
00052 #define NR_spu_run      0x0116
00053 
00054 /* If the PPU thread is currently stopped on a spu_run system call,
00055    return to FD and ADDR the file handle and NPC parameter address
00056    used with the system call.  Return non-zero if successful.  */
00057 static int
00058 parse_spufs_run (ptid_t ptid, int *fd, CORE_ADDR *addr)
00059 {
00060   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
00061   struct gdbarch_tdep *tdep;
00062   struct regcache *regcache;
00063   gdb_byte buf[4];
00064   ULONGEST regval;
00065 
00066   /* If we're not on PPU, there's nothing to detect.  */
00067   if (gdbarch_bfd_arch_info (target_gdbarch ())->arch != bfd_arch_powerpc)
00068     return 0;
00069 
00070   /* Get PPU-side registers.  */
00071   regcache = get_thread_arch_regcache (ptid, target_gdbarch ());
00072   tdep = gdbarch_tdep (target_gdbarch ());
00073 
00074   /* Fetch instruction preceding current NIP.  */
00075   if (target_read_memory (regcache_read_pc (regcache) - 4, buf, 4) != 0)
00076     return 0;
00077   /* It should be a "sc" instruction.  */
00078   if (extract_unsigned_integer (buf, 4, byte_order) != INSTR_SC)
00079     return 0;
00080   /* System call number should be NR_spu_run.  */
00081   regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum, &regval);
00082   if (regval != NR_spu_run)
00083     return 0;
00084 
00085   /* Register 3 contains fd, register 4 the NPC param pointer.  */
00086   regcache_cooked_read_unsigned (regcache, PPC_ORIG_R3_REGNUM, &regval);
00087   *fd = (int) regval;
00088   regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum + 4, &regval);
00089   *addr = (CORE_ADDR) regval;
00090   return 1;
00091 }
00092 
00093 /* Find gdbarch for SPU context SPUFS_FD.  */
00094 static struct gdbarch *
00095 spu_gdbarch (int spufs_fd)
00096 {
00097   struct gdbarch_info info;
00098   gdbarch_info_init (&info);
00099   info.bfd_arch_info = bfd_lookup_arch (bfd_arch_spu, bfd_mach_spu);
00100   info.byte_order = BFD_ENDIAN_BIG;
00101   info.osabi = GDB_OSABI_LINUX;
00102   info.tdep_info = (void *) &spufs_fd;
00103   return gdbarch_find_by_info (info);
00104 }
00105 
00106 /* Override the to_thread_architecture routine.  */
00107 static struct gdbarch *
00108 spu_thread_architecture (struct target_ops *ops, ptid_t ptid)
00109 {
00110   int spufs_fd;
00111   CORE_ADDR spufs_addr;
00112 
00113   if (parse_spufs_run (ptid, &spufs_fd, &spufs_addr))
00114     return spu_gdbarch (spufs_fd);
00115 
00116   return target_gdbarch ();
00117 }
00118 
00119 /* Override the to_region_ok_for_hw_watchpoint routine.  */
00120 static int
00121 spu_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
00122 {
00123   struct target_ops *ops_beneath = find_target_beneath (&spu_ops);
00124   while (ops_beneath && !ops_beneath->to_region_ok_for_hw_watchpoint)
00125     ops_beneath = find_target_beneath (ops_beneath);
00126 
00127   /* We cannot watch SPU local store.  */
00128   if (SPUADDR_SPU (addr) != -1)
00129     return 0;
00130 
00131   if (ops_beneath)
00132     return ops_beneath->to_region_ok_for_hw_watchpoint (addr, len);
00133 
00134   return 0;
00135 }
00136 
00137 /* Override the to_fetch_registers routine.  */
00138 static void
00139 spu_fetch_registers (struct target_ops *ops,
00140                      struct regcache *regcache, int regno)
00141 {
00142   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00143   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
00144   struct target_ops *ops_beneath = find_target_beneath (ops);
00145   int spufs_fd;
00146   CORE_ADDR spufs_addr;
00147 
00148   /* This version applies only if we're currently in spu_run.  */
00149   if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_spu)
00150     {
00151       while (ops_beneath && !ops_beneath->to_fetch_registers)
00152         ops_beneath = find_target_beneath (ops_beneath);
00153 
00154       gdb_assert (ops_beneath);
00155       ops_beneath->to_fetch_registers (ops_beneath, regcache, regno);
00156       return;
00157     }
00158 
00159   /* We must be stopped on a spu_run system call.  */
00160   if (!parse_spufs_run (inferior_ptid, &spufs_fd, &spufs_addr))
00161     return;
00162 
00163   /* The ID register holds the spufs file handle.  */
00164   if (regno == -1 || regno == SPU_ID_REGNUM)
00165     {
00166       gdb_byte buf[4];
00167       store_unsigned_integer (buf, 4, byte_order, spufs_fd);
00168       regcache_raw_supply (regcache, SPU_ID_REGNUM, buf);
00169     }
00170 
00171   /* The NPC register is found in PPC memory at SPUFS_ADDR.  */
00172   if (regno == -1 || regno == SPU_PC_REGNUM)
00173     {
00174       gdb_byte buf[4];
00175 
00176       if (target_read (ops_beneath, TARGET_OBJECT_MEMORY, NULL,
00177                        buf, spufs_addr, sizeof buf) == sizeof buf)
00178         regcache_raw_supply (regcache, SPU_PC_REGNUM, buf);
00179     }
00180 
00181   /* The GPRs are found in the "regs" spufs file.  */
00182   if (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))
00183     {
00184       gdb_byte buf[16 * SPU_NUM_GPRS];
00185       char annex[32];
00186       int i;
00187 
00188       xsnprintf (annex, sizeof annex, "%d/regs", spufs_fd);
00189       if (target_read (ops_beneath, TARGET_OBJECT_SPU, annex,
00190                        buf, 0, sizeof buf) == sizeof buf)
00191         for (i = 0; i < SPU_NUM_GPRS; i++)
00192           regcache_raw_supply (regcache, i, buf + i*16);
00193     }
00194 }
00195 
00196 /* Override the to_store_registers routine.  */
00197 static void
00198 spu_store_registers (struct target_ops *ops,
00199                      struct regcache *regcache, int regno)
00200 {
00201   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00202   struct target_ops *ops_beneath = find_target_beneath (ops);
00203   int spufs_fd;
00204   CORE_ADDR spufs_addr;
00205 
00206   /* This version applies only if we're currently in spu_run.  */
00207   if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_spu)
00208     {
00209       while (ops_beneath && !ops_beneath->to_fetch_registers)
00210         ops_beneath = find_target_beneath (ops_beneath);
00211 
00212       gdb_assert (ops_beneath);
00213       ops_beneath->to_store_registers (ops_beneath, regcache, regno);
00214       return;
00215     }
00216 
00217   /* We must be stopped on a spu_run system call.  */
00218   if (!parse_spufs_run (inferior_ptid, &spufs_fd, &spufs_addr))
00219     return;
00220 
00221   /* The NPC register is found in PPC memory at SPUFS_ADDR.  */
00222   if (regno == -1 || regno == SPU_PC_REGNUM)
00223     {
00224       gdb_byte buf[4];
00225       regcache_raw_collect (regcache, SPU_PC_REGNUM, buf);
00226 
00227       target_write (ops_beneath, TARGET_OBJECT_MEMORY, NULL,
00228                     buf, spufs_addr, sizeof buf);
00229     }
00230 
00231   /* The GPRs are found in the "regs" spufs file.  */
00232   if (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))
00233     {
00234       gdb_byte buf[16 * SPU_NUM_GPRS];
00235       char annex[32];
00236       int i;
00237 
00238       for (i = 0; i < SPU_NUM_GPRS; i++)
00239         regcache_raw_collect (regcache, i, buf + i*16);
00240 
00241       xsnprintf (annex, sizeof annex, "%d/regs", spufs_fd);
00242       target_write (ops_beneath, TARGET_OBJECT_SPU, annex,
00243                     buf, 0, sizeof buf);
00244     }
00245 }
00246 
00247 /* Override the to_xfer_partial routine.  */
00248 static LONGEST
00249 spu_xfer_partial (struct target_ops *ops, enum target_object object,
00250                   const char *annex, gdb_byte *readbuf,
00251                   const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
00252 {
00253   struct target_ops *ops_beneath = find_target_beneath (ops);
00254   while (ops_beneath && !ops_beneath->to_xfer_partial)
00255     ops_beneath = find_target_beneath (ops_beneath);
00256   gdb_assert (ops_beneath);
00257 
00258   /* Use the "mem" spufs file to access SPU local store.  */
00259   if (object == TARGET_OBJECT_MEMORY)
00260     {
00261       int fd = SPUADDR_SPU (offset);
00262       CORE_ADDR addr = SPUADDR_ADDR (offset);
00263       char mem_annex[32], lslr_annex[32];
00264       gdb_byte buf[32];
00265       ULONGEST lslr;
00266       LONGEST ret;
00267 
00268       if (fd >= 0)
00269         {
00270           xsnprintf (mem_annex, sizeof mem_annex, "%d/mem", fd);
00271           ret = ops_beneath->to_xfer_partial (ops_beneath, TARGET_OBJECT_SPU,
00272                                               mem_annex, readbuf, writebuf,
00273                                               addr, len);
00274           if (ret > 0)
00275             return ret;
00276 
00277           /* SPU local store access wraps the address around at the
00278              local store limit.  We emulate this here.  To avoid needing
00279              an extra access to retrieve the LSLR, we only do that after
00280              trying the original address first, and getting end-of-file.  */
00281           xsnprintf (lslr_annex, sizeof lslr_annex, "%d/lslr", fd);
00282           memset (buf, 0, sizeof buf);
00283           if (ops_beneath->to_xfer_partial (ops_beneath, TARGET_OBJECT_SPU,
00284                                             lslr_annex, buf, NULL,
00285                                             0, sizeof buf) <= 0)
00286             return ret;
00287 
00288           lslr = strtoulst ((char *) buf, NULL, 16);
00289           return ops_beneath->to_xfer_partial (ops_beneath, TARGET_OBJECT_SPU,
00290                                                mem_annex, readbuf, writebuf,
00291                                                addr & lslr, len);
00292         }
00293     }
00294 
00295   return ops_beneath->to_xfer_partial (ops_beneath, object, annex,
00296                                        readbuf, writebuf, offset, len);
00297 }
00298 
00299 /* Override the to_search_memory routine.  */
00300 static int
00301 spu_search_memory (struct target_ops* ops,
00302                    CORE_ADDR start_addr, ULONGEST search_space_len,
00303                    const gdb_byte *pattern, ULONGEST pattern_len,
00304                    CORE_ADDR *found_addrp)
00305 {
00306   struct target_ops *ops_beneath = find_target_beneath (ops);
00307   while (ops_beneath && !ops_beneath->to_search_memory)
00308     ops_beneath = find_target_beneath (ops_beneath);
00309 
00310   /* For SPU local store, always fall back to the simple method.  Likewise
00311      if we do not have any target-specific special implementation.  */
00312   if (!ops_beneath || SPUADDR_SPU (start_addr) >= 0)
00313     return simple_search_memory (ops,
00314                                  start_addr, search_space_len,
00315                                  pattern, pattern_len, found_addrp);
00316 
00317   return ops_beneath->to_search_memory (ops_beneath,
00318                                         start_addr, search_space_len,
00319                                         pattern, pattern_len, found_addrp);
00320 }
00321 
00322 
00323 /* Push and pop the SPU multi-architecture support target.  */
00324 
00325 static void
00326 spu_multiarch_activate (void)
00327 {
00328   /* If GDB was configured without SPU architecture support,
00329      we cannot install SPU multi-architecture support either.  */
00330   if (spu_gdbarch (-1) == NULL)
00331     return;
00332 
00333   push_target (&spu_ops);
00334 
00335   /* Make sure the thread architecture is re-evaluated.  */
00336   registers_changed ();
00337 }
00338 
00339 static void
00340 spu_multiarch_deactivate (void)
00341 {
00342   unpush_target (&spu_ops);
00343 
00344   /* Make sure the thread architecture is re-evaluated.  */
00345   registers_changed ();
00346 }
00347 
00348 static void
00349 spu_multiarch_inferior_created (struct target_ops *ops, int from_tty)
00350 {
00351   if (spu_standalone_p ())
00352     spu_multiarch_activate ();
00353 }
00354 
00355 static void
00356 spu_multiarch_solib_loaded (struct so_list *so)
00357 {
00358   if (!spu_standalone_p ())
00359     if (so->abfd && bfd_get_arch (so->abfd) == bfd_arch_spu)
00360       if (spu_nr_solib++ == 0)
00361         spu_multiarch_activate ();
00362 }
00363 
00364 static void
00365 spu_multiarch_solib_unloaded (struct so_list *so)
00366 {
00367   if (!spu_standalone_p ())
00368     if (so->abfd && bfd_get_arch (so->abfd) == bfd_arch_spu)
00369       if (--spu_nr_solib == 0)
00370         spu_multiarch_deactivate ();
00371 }
00372 
00373 static void
00374 spu_mourn_inferior (struct target_ops *ops)
00375 {
00376   struct target_ops *ops_beneath = find_target_beneath (ops);
00377   while (ops_beneath && !ops_beneath->to_mourn_inferior)
00378     ops_beneath = find_target_beneath (ops_beneath);
00379 
00380   gdb_assert (ops_beneath);
00381   ops_beneath->to_mourn_inferior (ops_beneath);
00382   spu_multiarch_deactivate ();
00383 }
00384 
00385 
00386 /* Initialize the SPU multi-architecture support target.  */
00387 
00388 static void
00389 init_spu_ops (void)
00390 {
00391   spu_ops.to_shortname = "spu";
00392   spu_ops.to_longname = "SPU multi-architecture support.";
00393   spu_ops.to_doc = "SPU multi-architecture support.";
00394   spu_ops.to_mourn_inferior = spu_mourn_inferior;
00395   spu_ops.to_fetch_registers = spu_fetch_registers;
00396   spu_ops.to_store_registers = spu_store_registers;
00397   spu_ops.to_xfer_partial = spu_xfer_partial;
00398   spu_ops.to_search_memory = spu_search_memory;
00399   spu_ops.to_region_ok_for_hw_watchpoint = spu_region_ok_for_hw_watchpoint;
00400   spu_ops.to_thread_architecture = spu_thread_architecture;
00401   spu_ops.to_stratum = arch_stratum;
00402   spu_ops.to_magic = OPS_MAGIC;
00403 }
00404 
00405 /* -Wmissing-prototypes */
00406 extern initialize_file_ftype _initialize_spu_multiarch;
00407 
00408 void
00409 _initialize_spu_multiarch (void)
00410 {
00411   /* Install ourselves on the target stack.  */
00412   init_spu_ops ();
00413   complete_target_initialization (&spu_ops);
00414 
00415   /* Install observers to watch for SPU objects.  */
00416   observer_attach_inferior_created (spu_multiarch_inferior_created);
00417   observer_attach_solib_loaded (spu_multiarch_solib_loaded);
00418   observer_attach_solib_unloaded (spu_multiarch_solib_unloaded);
00419 }
00420 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines