OSDN Git Service

*** empty log message ***
[pf3gnuchains/sourceware.git] / gdb / spu-linux-nat.c
index f6a3c79..db47292 100644 (file)
@@ -1,5 +1,6 @@
 /* SPU native-dependent code for GDB, the GNU debugger.
-   Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
+   Free Software Foundation, Inc.
 
    Contributed by Ulrich Weigand <uweigand@de.ibm.com>.
 
@@ -204,6 +205,7 @@ store_ppc_memory (ULONGEST memaddr, const gdb_byte *myaddr, int len)
 static int 
 parse_spufs_run (int *fd, ULONGEST *addr)
 {
+  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
   gdb_byte buf[4];
   ULONGEST pc = fetch_ppc_register (32);  /* nip */
 
@@ -211,7 +213,7 @@ parse_spufs_run (int *fd, ULONGEST *addr)
   if (fetch_ppc_memory (pc-4, buf, 4) != 0)
     return 0;
   /* It should be a "sc" instruction.  */
-  if (extract_unsigned_integer (buf, 4) != INSTR_SC)
+  if (extract_unsigned_integer (buf, 4, byte_order) != INSTR_SC)
     return 0;
   /* System call number should be NR_spu_run.  */
   if (fetch_ppc_register (0) != NR_spu_run)
@@ -483,8 +485,10 @@ spu_fetch_inferior_registers (struct target_ops *ops,
   /* The ID register holds the spufs file handle.  */
   if (regno == -1 || regno == SPU_ID_REGNUM)
     {
+      struct gdbarch *gdbarch = get_regcache_arch (regcache);
+      enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
       char buf[4];
-      store_unsigned_integer (buf, 4, fd);
+      store_unsigned_integer (buf, 4, byte_order, fd);
       regcache_raw_supply (regcache, SPU_ID_REGNUM, buf);
     }
 
@@ -559,7 +563,10 @@ spu_xfer_partial (struct target_ops *ops,
     {
       int fd;
       ULONGEST addr;
-      char mem_annex[32];
+      char mem_annex[32], lslr_annex[32];
+      gdb_byte buf[32];
+      ULONGEST lslr;
+      LONGEST ret;
 
       /* We must be stopped on a spu_run system call.  */
       if (!parse_spufs_run (&fd, &addr))
@@ -567,7 +574,22 @@ spu_xfer_partial (struct target_ops *ops,
 
       /* Use the "mem" spufs file to access SPU local store.  */
       xsnprintf (mem_annex, sizeof mem_annex, "%d/mem", fd);
-      return spu_proc_xfer_spu (mem_annex, readbuf, writebuf, offset, len);
+      ret = spu_proc_xfer_spu (mem_annex, readbuf, writebuf, offset, len);
+      if (ret > 0)
+       return ret;
+
+      /* SPU local store access wraps the address around at the
+        local store limit.  We emulate this here.  To avoid needing
+        an extra access to retrieve the LSLR, we only do that after
+        trying the original address first, and getting end-of-file.  */
+      xsnprintf (lslr_annex, sizeof lslr_annex, "%d/lslr", fd);
+      memset (buf, 0, sizeof buf);
+      if (spu_proc_xfer_spu (lslr_annex, buf, NULL, 0, sizeof buf) <= 0)
+       return ret;
+
+      lslr = strtoulst (buf, NULL, 16);
+      return spu_proc_xfer_spu (mem_annex, readbuf, writebuf,
+                               offset & lslr, len);
     }
 
   return -1;