/* SPU native-dependent code for GDB, the GNU debugger.
- Copyright (C) 2006 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2007 Free Software Foundation, Inc.
Contributed by Ulrich Weigand <uweigand@de.ibm.com>.
#include "regcache.h"
#include "symfile.h"
#include "gdb_wait.h"
+#include "gdb_stdint.h"
#include <sys/ptrace.h>
#include <asm/ptrace.h>
/* Fetch PPU register REGNO. */
-static CORE_ADDR
+static ULONGEST
fetch_ppc_register (int regno)
{
PTRACE_TYPE_RET res;
ptrace (PPC_PTRACE_PEEKUSR_3264, tid,
(PTRACE_TYPE_ARG3) (regno * 8 + 4), buf + 4);
if (errno == 0)
- return (CORE_ADDR) *(unsigned long long *)buf;
+ return (ULONGEST) *(uint64_t *)buf;
}
#endif
perror_with_name (_(mess));
}
- return (CORE_ADDR) (unsigned long) res;
+ return (ULONGEST) (unsigned long) res;
}
/* Fetch WORD from PPU memory at (aligned) MEMADDR in thread TID. */
static int
-fetch_ppc_memory_1 (int tid, CORE_ADDR memaddr, PTRACE_TYPE_RET *word)
+fetch_ppc_memory_1 (int tid, ULONGEST memaddr, PTRACE_TYPE_RET *word)
{
errno = 0;
#ifndef __powerpc64__
if (memaddr >> 32)
{
- unsigned long long addr_8 = (unsigned long long) memaddr;
+ uint64_t addr_8 = (uint64_t) memaddr;
ptrace (PPC_PTRACE_PEEKTEXT_3264, tid, (PTRACE_TYPE_ARG3) &addr_8, word);
}
else
/* Store WORD into PPU memory at (aligned) MEMADDR in thread TID. */
static int
-store_ppc_memory_1 (int tid, CORE_ADDR memaddr, PTRACE_TYPE_RET word)
+store_ppc_memory_1 (int tid, ULONGEST memaddr, PTRACE_TYPE_RET word)
{
errno = 0;
#ifndef __powerpc64__
if (memaddr >> 32)
{
- unsigned long long addr_8 = (unsigned long long) memaddr;
+ uint64_t addr_8 = (uint64_t) memaddr;
ptrace (PPC_PTRACE_POKEDATA_3264, tid, (PTRACE_TYPE_ARG3) &addr_8, word);
}
else
/* Fetch LEN bytes of PPU memory at MEMADDR to MYADDR. */
static int
-fetch_ppc_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
+fetch_ppc_memory (ULONGEST memaddr, gdb_byte *myaddr, int len)
{
int i, ret;
- CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_TYPE_RET);
+ ULONGEST addr = memaddr & -(ULONGEST) sizeof (PTRACE_TYPE_RET);
int count = ((((memaddr + len) - addr) + sizeof (PTRACE_TYPE_RET) - 1)
/ sizeof (PTRACE_TYPE_RET));
PTRACE_TYPE_RET *buffer;
buffer = (PTRACE_TYPE_RET *) alloca (count * sizeof (PTRACE_TYPE_RET));
for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET))
- if ((ret = fetch_ppc_memory_1 (tid, addr, &buffer[i])) != 0)
- return ret;
+ {
+ ret = fetch_ppc_memory_1 (tid, addr, &buffer[i]);
+ if (ret)
+ return ret;
+ }
memcpy (myaddr,
(char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)),
/* Store LEN bytes from MYADDR to PPU memory at MEMADDR. */
static int
-store_ppc_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, int len)
+store_ppc_memory (ULONGEST memaddr, const gdb_byte *myaddr, int len)
{
int i, ret;
- CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_TYPE_RET);
+ ULONGEST addr = memaddr & -(ULONGEST) sizeof (PTRACE_TYPE_RET);
int count = ((((memaddr + len) - addr) + sizeof (PTRACE_TYPE_RET) - 1)
/ sizeof (PTRACE_TYPE_RET));
PTRACE_TYPE_RET *buffer;
buffer = (PTRACE_TYPE_RET *) alloca (count * sizeof (PTRACE_TYPE_RET));
if (addr != memaddr || len < (int) sizeof (PTRACE_TYPE_RET))
- if ((ret = fetch_ppc_memory_1 (tid, addr, &buffer[0])) != 0)
- return ret;
+ {
+ ret = fetch_ppc_memory_1 (tid, addr, &buffer[0]);
+ if (ret)
+ return ret;
+ }
if (count > 1)
- if ((ret = fetch_ppc_memory_1 (tid, addr + (count - 1)
+ {
+ ret = fetch_ppc_memory_1 (tid, addr + (count - 1)
* sizeof (PTRACE_TYPE_RET),
- &buffer[count - 1])) != 0)
- return ret;
+ &buffer[count - 1]);
+ if (ret)
+ return ret;
+ }
memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)),
myaddr, len);
for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET))
- if ((ret = store_ppc_memory_1 (tid, addr, buffer[i])) != 0)
- return ret;
+ {
+ ret = store_ppc_memory_1 (tid, addr, buffer[i]);
+ if (ret)
+ return ret;
+ }
return 0;
}
return to FD and ADDR the file handle and NPC parameter address
used with the system call. Return non-zero if successful. */
static int
-parse_spufs_run (int *fd, CORE_ADDR *addr)
+parse_spufs_run (int *fd, ULONGEST *addr)
{
gdb_byte buf[4];
- CORE_ADDR pc = fetch_ppc_register (32); /* nip */
+ ULONGEST pc = fetch_ppc_register (32); /* nip */
/* Fetch instruction preceding current NIP. */
if (fetch_ppc_memory (pc-4, buf, 4) != 0)
&& lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
{
close (fd);
- return -1;
+ return 0;
}
if (writebuf)
spu_bfd_iovec_pread (struct bfd *abfd, void *stream, void *buf,
file_ptr nbytes, file_ptr offset)
{
- CORE_ADDR addr = *(CORE_ADDR *)stream;
+ ULONGEST addr = *(ULONGEST *)stream;
if (fetch_ppc_memory (addr + offset, buf, nbytes) != 0)
{
return nbytes;
}
+static int
+spu_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb)
+{
+ /* We don't have an easy way of finding the size of embedded spu
+ images. We could parse the in-memory ELF header and section
+ table to find the extent of the last section but that seems
+ pointless when the size is needed only for checks of other
+ parsed values in dbxread.c. */
+ sb->st_size = INT_MAX;
+ return 0;
+}
+
static bfd *
-spu_bfd_open (CORE_ADDR addr)
+spu_bfd_open (ULONGEST addr)
{
struct bfd *nbfd;
- CORE_ADDR *open_closure = xmalloc (sizeof (CORE_ADDR));
+ ULONGEST *open_closure = xmalloc (sizeof (ULONGEST));
*open_closure = addr;
nbfd = bfd_openr_iovec (xstrdup ("<in-memory>"), "elf32-spu",
spu_bfd_iovec_open, open_closure,
- spu_bfd_iovec_pread, spu_bfd_iovec_close);
+ spu_bfd_iovec_pread, spu_bfd_iovec_close,
+ spu_bfd_iovec_stat);
if (!nbfd)
return NULL;
static void
spu_symbol_file_add_from_memory (int inferior_fd)
{
- CORE_ADDR addr;
+ ULONGEST addr;
struct bfd *nbfd;
char id[128];
if (len <= 0 || len >= sizeof id)
return;
id[len] = 0;
- if (sscanf (id, "0x%llx", &addr) != 1)
+ addr = strtoulst (id, NULL, 16);
+ if (!addr)
return;
/* Open BFD representing SPE executable and read its symbols. */
spu_child_post_startup_inferior (ptid_t ptid)
{
int fd;
- CORE_ADDR addr;
+ ULONGEST addr;
int tid = TIDGET (ptid);
if (tid == 0)
spu_child_post_attach (int pid)
{
int fd;
- CORE_ADDR addr;
+ ULONGEST addr;
/* Like child_post_startup_inferior, if we happened to attach to
the inferior while it wasn't currently in spu_run, continue
if (pid == -1)
{
- warning ("Child process unexpectedly missing: %s",
+ warning (_("Child process unexpectedly missing: %s"),
safe_strerror (save_errno));
/* Claim it exited with unknown signal. */
/* Override the fetch_inferior_register routine. */
static void
-spu_fetch_inferior_registers (int regno)
+spu_fetch_inferior_registers (struct regcache *regcache, int regno)
{
int fd;
- CORE_ADDR addr;
+ ULONGEST addr;
/* We must be stopped on a spu_run system call. */
if (!parse_spufs_run (&fd, &addr))
{
char buf[4];
store_unsigned_integer (buf, 4, fd);
- regcache_raw_supply (current_regcache, SPU_ID_REGNUM, buf);
+ regcache_raw_supply (regcache, SPU_ID_REGNUM, buf);
}
/* The NPC register is found at ADDR. */
{
gdb_byte buf[4];
if (fetch_ppc_memory (addr, buf, 4) == 0)
- regcache_raw_supply (current_regcache, SPU_PC_REGNUM, buf);
+ regcache_raw_supply (regcache, SPU_PC_REGNUM, buf);
}
/* The GPRs are found in the "regs" spufs file. */
xsnprintf (annex, sizeof annex, "%d/regs", fd);
if (spu_proc_xfer_spu (annex, buf, NULL, 0, sizeof buf) == sizeof buf)
for (i = 0; i < SPU_NUM_GPRS; i++)
- regcache_raw_supply (current_regcache, i, buf + i*16);
+ regcache_raw_supply (regcache, i, buf + i*16);
}
}
/* Override the store_inferior_register routine. */
static void
-spu_store_inferior_registers (int regno)
+spu_store_inferior_registers (struct regcache *regcache, int regno)
{
int fd;
- CORE_ADDR addr;
+ ULONGEST addr;
/* We must be stopped on a spu_run system call. */
if (!parse_spufs_run (&fd, &addr))
if (regno == -1 || regno == SPU_PC_REGNUM)
{
gdb_byte buf[4];
- regcache_raw_collect (current_regcache, SPU_PC_REGNUM, buf);
+ regcache_raw_collect (regcache, SPU_PC_REGNUM, buf);
store_ppc_memory (addr, buf, 4);
}
int i;
for (i = 0; i < SPU_NUM_GPRS; i++)
- regcache_raw_collect (current_regcache, i, buf + i*16);
+ regcache_raw_collect (regcache, i, buf + i*16);
xsnprintf (annex, sizeof annex, "%d/regs", fd);
spu_proc_xfer_spu (annex, NULL, buf, 0, sizeof buf);
gdb_byte *readbuf, const gdb_byte *writebuf,
ULONGEST offset, LONGEST len)
{
+ if (object == TARGET_OBJECT_SPU)
+ return spu_proc_xfer_spu (annex, readbuf, writebuf, offset, len);
+
if (object == TARGET_OBJECT_MEMORY)
{
int fd;
- CORE_ADDR addr;
+ ULONGEST addr;
char mem_annex[32];
/* We must be stopped on a spu_run system call. */
return spu_proc_xfer_spu (mem_annex, readbuf, writebuf, offset, len);
}
- return 0;
+ return -1;
}
/* Override the to_can_use_hw_breakpoint routine. */