X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gdb%2Fspu-linux-nat.c;h=2dfec8c12889d1c5fc52c13fe3a08fbff240e517;hb=a493e3e2e429e4832b8620bd920ad07d0c2892d7;hp=8d49baf31dc531bf2f1ba5b4294bca5901744dcc;hpb=6aba47ca06d9150c6196a374b745c2711b46e045;p=platform%2Fupstream%2Fbinutils.git diff --git a/gdb/spu-linux-nat.c b/gdb/spu-linux-nat.c index 8d49baf..2dfec8c 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-2012 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,19 +16,19 @@ 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" #include "gdb_string.h" #include "target.h" #include "inferior.h" +#include "inf-child.h" #include "inf-ptrace.h" #include "regcache.h" #include "symfile.h" #include "gdb_wait.h" +#include "gdbthread.h" #include #include @@ -43,7 +43,7 @@ /* Fetch PPU register REGNO. */ -static CORE_ADDR +static ULONGEST fetch_ppc_register (int regno) { PTRACE_TYPE_RET res; @@ -67,7 +67,7 @@ fetch_ppc_register (int regno) 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 @@ -81,19 +81,19 @@ fetch_ppc_register (int regno) 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 @@ -105,14 +105,14 @@ fetch_ppc_memory_1 (int tid, CORE_ADDR memaddr, PTRACE_TYPE_RET *word) /* 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 @@ -124,11 +124,11 @@ store_ppc_memory_1 (int tid, CORE_ADDR memaddr, PTRACE_TYPE_RET word) /* 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; @@ -139,8 +139,11 @@ fetch_ppc_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len) 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)), @@ -151,11 +154,11 @@ fetch_ppc_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len) /* 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; @@ -167,21 +170,30 @@ store_ppc_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, int len) 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; } @@ -191,16 +203,17 @@ store_ppc_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, int len) 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) { + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); 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) 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) @@ -237,7 +250,7 @@ spu_proc_xfer_spu (const char *annex, gdb_byte *readbuf, && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset) { close (fd); - return -1; + return 0; } if (writebuf) @@ -270,7 +283,7 @@ static file_ptr 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) { @@ -294,11 +307,12 @@ spu_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb) } static bfd * -spu_bfd_open (CORE_ADDR addr) +spu_bfd_open (ULONGEST addr) { struct bfd *nbfd; + asection *spu_name; - CORE_ADDR *open_closure = xmalloc (sizeof (CORE_ADDR)); + ULONGEST *open_closure = xmalloc (sizeof (ULONGEST)); *open_closure = addr; nbfd = bfd_openr_iovec (xstrdup (""), "elf32-spu", @@ -314,6 +328,22 @@ spu_bfd_open (CORE_ADDR 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; } @@ -324,7 +354,7 @@ spu_bfd_open (CORE_ADDR addr) static void spu_symbol_file_add_from_memory (int inferior_fd) { - CORE_ADDR addr; + ULONGEST addr; struct bfd *nbfd; char id[128]; @@ -337,13 +367,15 @@ spu_symbol_file_add_from_memory (int inferior_fd) 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. */ 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, NULL); } @@ -353,7 +385,7 @@ static void spu_child_post_startup_inferior (ptid_t ptid) { int fd; - CORE_ADDR addr; + ULONGEST addr; int tid = TIDGET (ptid); if (tid == 0) @@ -372,7 +404,7 @@ static void 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 @@ -392,7 +424,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; @@ -402,7 +435,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) @@ -419,20 +451,19 @@ 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); 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. */ ourstatus->kind = TARGET_WAITKIND_SIGNALLED; - ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN; - return minus_one_ptid; + ourstatus->value.sig = GDB_SIGNAL_UNKNOWN; + return inferior_ptid; } store_waitstatus (ourstatus, status); @@ -441,10 +472,11 @@ spu_child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) /* Override the fetch_inferior_register routine. */ static void -spu_fetch_inferior_registers (int regno) +spu_fetch_inferior_registers (struct target_ops *ops, + 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)) @@ -453,9 +485,11 @@ spu_fetch_inferior_registers (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); - regcache_raw_supply (current_regcache, SPU_ID_REGNUM, buf); + store_unsigned_integer (buf, 4, byte_order, fd); + regcache_raw_supply (regcache, SPU_ID_REGNUM, buf); } /* The NPC register is found at ADDR. */ @@ -463,7 +497,7 @@ spu_fetch_inferior_registers (int regno) { 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. */ @@ -476,16 +510,17 @@ spu_fetch_inferior_registers (int regno) 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 target_ops *ops, + 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)) @@ -495,7 +530,7 @@ spu_store_inferior_registers (int regno) 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); } @@ -507,7 +542,7 @@ spu_store_inferior_registers (int regno) 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); @@ -521,11 +556,17 @@ spu_xfer_partial (struct target_ops *ops, 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; - char mem_annex[32]; + ULONGEST addr; + 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)) @@ -533,10 +574,25 @@ 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 0; + return -1; } /* Override the to_can_use_hw_breakpoint routine. */ @@ -567,4 +623,3 @@ _initialize_spu_nat (void) /* Register SPU target. */ add_target (t); } -