/* Cell SPU GNU/Linux multi-architecture debugging support.
- Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 2009-2012 Free Software Foundation, Inc.
Contributed by Ulrich Weigand <uweigand@de.ibm.com>.
static int
parse_spufs_run (ptid_t ptid, int *fd, CORE_ADDR *addr)
{
- enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
struct gdbarch_tdep *tdep;
struct regcache *regcache;
char buf[4];
- CORE_ADDR pc;
ULONGEST regval;
/* If we're not on PPU, there's nothing to detect. */
- if (gdbarch_bfd_arch_info (target_gdbarch)->arch != bfd_arch_powerpc)
+ if (gdbarch_bfd_arch_info (target_gdbarch ())->arch != bfd_arch_powerpc)
return 0;
/* Get PPU-side registers. */
- regcache = get_thread_arch_regcache (ptid, target_gdbarch);
- tdep = gdbarch_tdep (target_gdbarch);
+ regcache = get_thread_arch_regcache (ptid, target_gdbarch ());
+ tdep = gdbarch_tdep (target_gdbarch ());
/* Fetch instruction preceding current NIP. */
if (target_read_memory (regcache_read_pc (regcache) - 4, buf, 4) != 0)
if (parse_spufs_run (ptid, &spufs_fd, &spufs_addr))
return spu_gdbarch (spufs_fd);
- return target_gdbarch;
+ return target_gdbarch ();
}
/* Override the to_region_ok_for_hw_watchpoint routine. */
{
int fd = SPUADDR_SPU (offset);
CORE_ADDR addr = SPUADDR_ADDR (offset);
- char mem_annex[32];
+ char mem_annex[32], lslr_annex[32];
+ gdb_byte buf[32];
+ ULONGEST lslr;
+ LONGEST ret;
- if (fd >= 0 && addr < SPU_LS_SIZE)
+ if (fd >= 0)
{
xsnprintf (mem_annex, sizeof mem_annex, "%d/mem", fd);
+ ret = ops_beneath->to_xfer_partial (ops_beneath, TARGET_OBJECT_SPU,
+ mem_annex, readbuf, writebuf,
+ addr, 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 (ops_beneath->to_xfer_partial (ops_beneath, TARGET_OBJECT_SPU,
+ lslr_annex, buf, NULL,
+ 0, sizeof buf) <= 0)
+ return ret;
+
+ lslr = strtoulst (buf, NULL, 16);
return ops_beneath->to_xfer_partial (ops_beneath, TARGET_OBJECT_SPU,
mem_annex, readbuf, writebuf,
- addr, len);
+ addr & lslr, len);
}
}
spu_ops.to_magic = OPS_MAGIC;
}
+/* -Wmissing-prototypes */
+extern initialize_file_ftype _initialize_spu_multiarch;
+
void
_initialize_spu_multiarch (void)
{