X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fspu-linux-nat.c;h=5adfe4baba75160ca874f022e35d433c69f24f40;hb=e7fbb131d42983eec31231f8bb69cdd8d5a33ee6;hp=3a03f2253367c98422669ef1070ea6f694d79450;hpb=23d964e7b6625bec3822bcb9613f65362b9b3026;p=binutils-gdb.git diff --git a/gdb/spu-linux-nat.c b/gdb/spu-linux-nat.c index 3a03f225336..5adfe4baba7 100644 --- a/gdb/spu-linux-nat.c +++ b/gdb/spu-linux-nat.c @@ -1,5 +1,5 @@ /* SPU native-dependent code for GDB, the GNU debugger. - Copyright (C) 2006, 2007 Free Software Foundation, Inc. + Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Ulrich Weigand . @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,9 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ #include "defs.h" #include "gdbcore.h" @@ -29,7 +27,7 @@ #include "regcache.h" #include "symfile.h" #include "gdb_wait.h" -#include "gdb_stdint.h" +#include "gdbthread.h" #include #include @@ -206,6 +204,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 */ @@ -213,7 +212,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) @@ -310,6 +309,7 @@ static bfd * spu_bfd_open (ULONGEST addr) { struct bfd *nbfd; + asection *spu_name; ULONGEST *open_closure = xmalloc (sizeof (ULONGEST)); *open_closure = addr; @@ -327,6 +327,22 @@ spu_bfd_open (ULONGEST addr) return NULL; } + /* Retrieve SPU name note and update BFD name. */ + spu_name = bfd_get_section_by_name (nbfd, ".note.spu_name"); + if (spu_name) + { + int sect_size = bfd_section_size (nbfd, spu_name); + if (sect_size > 20) + { + char *buf = alloca (sect_size - 20 + 1); + bfd_get_section_contents (nbfd, spu_name, buf, 20, sect_size - 20); + buf[sect_size - 20] = '\0'; + + xfree ((char *)nbfd->filename); + nbfd->filename = xstrdup (buf); + } + } + return nbfd; } @@ -357,7 +373,8 @@ spu_symbol_file_add_from_memory (int inferior_fd) /* Open BFD representing SPE executable and read its symbols. */ nbfd = spu_bfd_open (addr); if (nbfd) - symbol_file_add_from_bfd (nbfd, 0, NULL, 1, 0); + symbol_file_add_from_bfd (nbfd, SYMFILE_VERBOSE | SYMFILE_MAINLINE, + NULL, 0); } @@ -406,7 +423,8 @@ spu_child_post_attach (int pid) /* Wait for child PTID to do something. Return id of the child, minus_one_ptid in case of error; store status into *OURSTATUS. */ static ptid_t -spu_child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) +spu_child_wait (struct target_ops *ops, + ptid_t ptid, struct target_waitstatus *ourstatus, int options) { int save_errno; int status; @@ -416,7 +434,6 @@ spu_child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) { set_sigint_trap (); /* Causes SIGINT to be passed on to the attached process. */ - set_sigio_trap (); pid = waitpid (PIDGET (ptid), &status, 0); if (pid == -1 && errno == ECHILD) @@ -433,7 +450,6 @@ spu_child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) save_errno = EINTR; } - clear_sigio_trap (); clear_sigint_trap (); } while (pid == -1 && save_errno == EINTR); @@ -446,7 +462,7 @@ spu_child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) /* Claim it exited with unknown signal. */ ourstatus->kind = TARGET_WAITKIND_SIGNALLED; ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN; - return minus_one_ptid; + return inferior_ptid; } store_waitstatus (ourstatus, status); @@ -455,7 +471,8 @@ spu_child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) /* Override the fetch_inferior_register routine. */ static void -spu_fetch_inferior_registers (struct regcache *regcache, int regno) +spu_fetch_inferior_registers (struct target_ops *ops, + struct regcache *regcache, int regno) { int fd; ULONGEST addr; @@ -467,8 +484,10 @@ spu_fetch_inferior_registers (struct regcache *regcache, int regno) /* 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); } @@ -496,7 +515,8 @@ spu_fetch_inferior_registers (struct regcache *regcache, int regno) /* Override the store_inferior_register routine. */ static void -spu_store_inferior_registers (struct regcache *regcache, int regno) +spu_store_inferior_registers (struct target_ops *ops, + struct regcache *regcache, int regno) { int fd; ULONGEST addr; @@ -542,7 +562,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)) @@ -550,7 +573,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; @@ -584,4 +622,3 @@ _initialize_spu_nat (void) /* Register SPU target. */ add_target (t); } -