GDB (API)
/home/stan/gdb/src/gdb/spu-linux-nat.c
Go to the documentation of this file.
00001 /* SPU native-dependent code for GDB, the GNU debugger.
00002    Copyright (C) 2006-2013 Free Software Foundation, Inc.
00003 
00004    Contributed by Ulrich Weigand <uweigand@de.ibm.com>.
00005 
00006    This file is part of GDB.
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 3 of the License, or
00011    (at your option) any later version.
00012 
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00020 
00021 #include "defs.h"
00022 #include "gdbcore.h"
00023 #include "gdb_string.h"
00024 #include "target.h"
00025 #include "inferior.h"
00026 #include "inf-child.h"
00027 #include "inf-ptrace.h"
00028 #include "regcache.h"
00029 #include "symfile.h"
00030 #include "gdb_wait.h"
00031 #include "gdbthread.h"
00032 #include "gdb_bfd.h"
00033 
00034 #include <sys/ptrace.h>
00035 #include <asm/ptrace.h>
00036 #include <sys/types.h>
00037 
00038 #include "spu-tdep.h"
00039 
00040 /* PPU side system calls.  */
00041 #define INSTR_SC        0x44000002
00042 #define NR_spu_run      0x0116
00043 
00044 
00045 /* Fetch PPU register REGNO.  */
00046 static ULONGEST
00047 fetch_ppc_register (int regno)
00048 {
00049   PTRACE_TYPE_RET res;
00050 
00051   int tid = ptid_get_lwp (inferior_ptid);
00052   if (tid == 0)
00053     tid = ptid_get_pid (inferior_ptid);
00054 
00055 #ifndef __powerpc64__
00056   /* If running as a 32-bit process on a 64-bit system, we attempt
00057      to get the full 64-bit register content of the target process.
00058      If the PPC special ptrace call fails, we're on a 32-bit system;
00059      just fall through to the regular ptrace call in that case.  */
00060   {
00061     gdb_byte buf[8];
00062 
00063     errno = 0;
00064     ptrace (PPC_PTRACE_PEEKUSR_3264, tid,
00065             (PTRACE_TYPE_ARG3) (regno * 8), buf);
00066     if (errno == 0)
00067       ptrace (PPC_PTRACE_PEEKUSR_3264, tid,
00068               (PTRACE_TYPE_ARG3) (regno * 8 + 4), buf + 4);
00069     if (errno == 0)
00070       return (ULONGEST) *(uint64_t *)buf;
00071   }
00072 #endif
00073 
00074   errno = 0;
00075   res = ptrace (PT_READ_U, tid,
00076                 (PTRACE_TYPE_ARG3) (regno * sizeof (PTRACE_TYPE_RET)), 0);
00077   if (errno != 0)
00078     {
00079       char mess[128];
00080       xsnprintf (mess, sizeof mess, "reading PPC register #%d", regno);
00081       perror_with_name (_(mess));
00082     }
00083 
00084   return (ULONGEST) (unsigned long) res;
00085 }
00086 
00087 /* Fetch WORD from PPU memory at (aligned) MEMADDR in thread TID.  */
00088 static int
00089 fetch_ppc_memory_1 (int tid, ULONGEST memaddr, PTRACE_TYPE_RET *word)
00090 {
00091   errno = 0;
00092 
00093 #ifndef __powerpc64__
00094   if (memaddr >> 32)
00095     {
00096       uint64_t addr_8 = (uint64_t) memaddr;
00097       ptrace (PPC_PTRACE_PEEKTEXT_3264, tid, (PTRACE_TYPE_ARG3) &addr_8, word);
00098     }
00099   else
00100 #endif
00101     *word = ptrace (PT_READ_I, tid, (PTRACE_TYPE_ARG3) (size_t) memaddr, 0);
00102 
00103   return errno;
00104 }
00105 
00106 /* Store WORD into PPU memory at (aligned) MEMADDR in thread TID.  */
00107 static int
00108 store_ppc_memory_1 (int tid, ULONGEST memaddr, PTRACE_TYPE_RET word)
00109 {
00110   errno = 0;
00111 
00112 #ifndef __powerpc64__
00113   if (memaddr >> 32)
00114     {
00115       uint64_t addr_8 = (uint64_t) memaddr;
00116       ptrace (PPC_PTRACE_POKEDATA_3264, tid, (PTRACE_TYPE_ARG3) &addr_8, word);
00117     }
00118   else
00119 #endif
00120     ptrace (PT_WRITE_D, tid, (PTRACE_TYPE_ARG3) (size_t) memaddr, word);
00121 
00122   return errno;
00123 }
00124 
00125 /* Fetch LEN bytes of PPU memory at MEMADDR to MYADDR.  */
00126 static int
00127 fetch_ppc_memory (ULONGEST memaddr, gdb_byte *myaddr, int len)
00128 {
00129   int i, ret;
00130 
00131   ULONGEST addr = memaddr & -(ULONGEST) sizeof (PTRACE_TYPE_RET);
00132   int count = ((((memaddr + len) - addr) + sizeof (PTRACE_TYPE_RET) - 1)
00133                / sizeof (PTRACE_TYPE_RET));
00134   PTRACE_TYPE_RET *buffer;
00135 
00136   int tid = ptid_get_lwp (inferior_ptid);
00137   if (tid == 0)
00138     tid = ptid_get_pid (inferior_ptid);
00139 
00140   buffer = (PTRACE_TYPE_RET *) alloca (count * sizeof (PTRACE_TYPE_RET));
00141   for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET))
00142     {
00143       ret = fetch_ppc_memory_1 (tid, addr, &buffer[i]);
00144       if (ret)
00145         return ret;
00146     }
00147 
00148   memcpy (myaddr,
00149           (char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)),
00150           len);
00151 
00152   return 0;
00153 }
00154 
00155 /* Store LEN bytes from MYADDR to PPU memory at MEMADDR.  */
00156 static int
00157 store_ppc_memory (ULONGEST memaddr, const gdb_byte *myaddr, int len)
00158 {
00159   int i, ret;
00160 
00161   ULONGEST addr = memaddr & -(ULONGEST) sizeof (PTRACE_TYPE_RET);
00162   int count = ((((memaddr + len) - addr) + sizeof (PTRACE_TYPE_RET) - 1)
00163                / sizeof (PTRACE_TYPE_RET));
00164   PTRACE_TYPE_RET *buffer;
00165 
00166   int tid = ptid_get_lwp (inferior_ptid);
00167   if (tid == 0)
00168     tid = ptid_get_pid (inferior_ptid);
00169 
00170   buffer = (PTRACE_TYPE_RET *) alloca (count * sizeof (PTRACE_TYPE_RET));
00171 
00172   if (addr != memaddr || len < (int) sizeof (PTRACE_TYPE_RET))
00173     {
00174       ret = fetch_ppc_memory_1 (tid, addr, &buffer[0]);
00175       if (ret)
00176         return ret;
00177     }
00178 
00179   if (count > 1)
00180     {
00181       ret = fetch_ppc_memory_1 (tid, addr + (count - 1)
00182                                                * sizeof (PTRACE_TYPE_RET),
00183                                 &buffer[count - 1]);
00184       if (ret)
00185         return ret;
00186     }
00187 
00188   memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)),
00189           myaddr, len);
00190 
00191   for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET))
00192     {
00193       ret = store_ppc_memory_1 (tid, addr, buffer[i]);
00194       if (ret)
00195         return ret;
00196     }
00197 
00198   return 0;
00199 }
00200 
00201 
00202 /* If the PPU thread is currently stopped on a spu_run system call,
00203    return to FD and ADDR the file handle and NPC parameter address
00204    used with the system call.  Return non-zero if successful.  */
00205 static int 
00206 parse_spufs_run (int *fd, ULONGEST *addr)
00207 {
00208   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
00209   gdb_byte buf[4];
00210   ULONGEST pc = fetch_ppc_register (32);  /* nip */
00211 
00212   /* Fetch instruction preceding current NIP.  */
00213   if (fetch_ppc_memory (pc-4, buf, 4) != 0)
00214     return 0;
00215   /* It should be a "sc" instruction.  */
00216   if (extract_unsigned_integer (buf, 4, byte_order) != INSTR_SC)
00217     return 0;
00218   /* System call number should be NR_spu_run.  */
00219   if (fetch_ppc_register (0) != NR_spu_run)
00220     return 0;
00221 
00222   /* Register 3 contains fd, register 4 the NPC param pointer.  */
00223   *fd = fetch_ppc_register (34);  /* orig_gpr3 */
00224   *addr = fetch_ppc_register (4);
00225   return 1;
00226 }
00227 
00228 
00229 /* Copy LEN bytes at OFFSET in spufs file ANNEX into/from READBUF or WRITEBUF,
00230    using the /proc file system.  */
00231 static LONGEST
00232 spu_proc_xfer_spu (const char *annex, gdb_byte *readbuf,
00233                    const gdb_byte *writebuf,
00234                    ULONGEST offset, LONGEST len)
00235 {
00236   char buf[128];
00237   int fd = 0;
00238   int ret = -1;
00239   int pid = ptid_get_pid (inferior_ptid);
00240 
00241   if (!annex)
00242     return 0;
00243 
00244   xsnprintf (buf, sizeof buf, "/proc/%d/fd/%s", pid, annex);
00245   fd = open (buf, writebuf? O_WRONLY : O_RDONLY);
00246   if (fd <= 0)
00247     return -1;
00248 
00249   if (offset != 0
00250       && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
00251     {
00252       close (fd);
00253       return 0;
00254     }
00255 
00256   if (writebuf)
00257     ret = write (fd, writebuf, (size_t) len);
00258   else if (readbuf)
00259     ret = read (fd, readbuf, (size_t) len);
00260 
00261   close (fd);
00262   return ret;
00263 }
00264 
00265 
00266 /* Inferior memory should contain an SPE executable image at location ADDR.
00267    Allocate a BFD representing that executable.  Return NULL on error.  */
00268 
00269 static void *
00270 spu_bfd_iovec_open (struct bfd *nbfd, void *open_closure)
00271 {
00272   return open_closure;
00273 }
00274 
00275 static int
00276 spu_bfd_iovec_close (struct bfd *nbfd, void *stream)
00277 {
00278   xfree (stream);
00279 
00280   /* Zero means success.  */
00281   return 0;
00282 }
00283 
00284 static file_ptr
00285 spu_bfd_iovec_pread (struct bfd *abfd, void *stream, void *buf,
00286                      file_ptr nbytes, file_ptr offset)
00287 {
00288   ULONGEST addr = *(ULONGEST *)stream;
00289 
00290   if (fetch_ppc_memory (addr + offset, buf, nbytes) != 0)
00291     {
00292       bfd_set_error (bfd_error_invalid_operation);
00293       return -1;
00294     }
00295 
00296   return nbytes;
00297 }
00298 
00299 static int
00300 spu_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb)
00301 {
00302   /* We don't have an easy way of finding the size of embedded spu
00303      images.  We could parse the in-memory ELF header and section
00304      table to find the extent of the last section but that seems
00305      pointless when the size is needed only for checks of other
00306      parsed values in dbxread.c.  */
00307   sb->st_size = INT_MAX;
00308   return 0;
00309 }
00310 
00311 static bfd *
00312 spu_bfd_open (ULONGEST addr)
00313 {
00314   struct bfd *nbfd;
00315   asection *spu_name;
00316 
00317   ULONGEST *open_closure = xmalloc (sizeof (ULONGEST));
00318   *open_closure = addr;
00319 
00320   nbfd = gdb_bfd_openr_iovec ("<in-memory>", "elf32-spu",
00321                               spu_bfd_iovec_open, open_closure,
00322                               spu_bfd_iovec_pread, spu_bfd_iovec_close,
00323                               spu_bfd_iovec_stat);
00324   if (!nbfd)
00325     return NULL;
00326 
00327   if (!bfd_check_format (nbfd, bfd_object))
00328     {
00329       gdb_bfd_unref (nbfd);
00330       return NULL;
00331     }
00332 
00333   /* Retrieve SPU name note and update BFD name.  */
00334   spu_name = bfd_get_section_by_name (nbfd, ".note.spu_name");
00335   if (spu_name)
00336     {
00337       int sect_size = bfd_section_size (nbfd, spu_name);
00338       if (sect_size > 20)
00339         {
00340           char *buf = alloca (sect_size - 20 + 1);
00341           bfd_get_section_contents (nbfd, spu_name, buf, 20, sect_size - 20);
00342           buf[sect_size - 20] = '\0';
00343 
00344           xfree ((char *)nbfd->filename);
00345           nbfd->filename = xstrdup (buf);
00346         }
00347     }
00348 
00349   return nbfd;
00350 }
00351 
00352 /* INFERIOR_FD is a file handle passed by the inferior to the
00353    spu_run system call.  Assuming the SPE context was allocated
00354    by the libspe library, try to retrieve the main SPE executable
00355    file from its copy within the target process.  */
00356 static void
00357 spu_symbol_file_add_from_memory (int inferior_fd)
00358 {
00359   ULONGEST addr;
00360   struct bfd *nbfd;
00361 
00362   char id[128];
00363   char annex[32];
00364   int len;
00365 
00366   /* Read object ID.  */
00367   xsnprintf (annex, sizeof annex, "%d/object-id", inferior_fd);
00368   len = spu_proc_xfer_spu (annex, id, NULL, 0, sizeof id);
00369   if (len <= 0 || len >= sizeof id)
00370     return;
00371   id[len] = 0;
00372   addr = strtoulst (id, NULL, 16);
00373   if (!addr)
00374     return;
00375 
00376   /* Open BFD representing SPE executable and read its symbols.  */
00377   nbfd = spu_bfd_open (addr);
00378   if (nbfd)
00379     {
00380       struct cleanup *cleanup = make_cleanup_bfd_unref (nbfd);
00381 
00382       symbol_file_add_from_bfd (nbfd, SYMFILE_VERBOSE | SYMFILE_MAINLINE,
00383                                 NULL, 0, NULL);
00384       do_cleanups (cleanup);
00385     }
00386 }
00387 
00388 
00389 /* Override the post_startup_inferior routine to continue running
00390    the inferior until the first spu_run system call.  */
00391 static void
00392 spu_child_post_startup_inferior (ptid_t ptid)
00393 {
00394   int fd;
00395   ULONGEST addr;
00396 
00397   int tid = ptid_get_lwp (ptid);
00398   if (tid == 0)
00399     tid = ptid_get_pid (ptid);
00400   
00401   while (!parse_spufs_run (&fd, &addr))
00402     {
00403       ptrace (PT_SYSCALL, tid, (PTRACE_TYPE_ARG3) 0, 0);
00404       waitpid (tid, NULL, __WALL | __WNOTHREAD);
00405     }
00406 }
00407 
00408 /* Override the post_attach routine to try load the SPE executable
00409    file image from its copy inside the target process.  */
00410 static void
00411 spu_child_post_attach (int pid)
00412 {
00413   int fd;
00414   ULONGEST addr;
00415 
00416   /* Like child_post_startup_inferior, if we happened to attach to
00417      the inferior while it wasn't currently in spu_run, continue 
00418      running it until we get back there.  */
00419   while (!parse_spufs_run (&fd, &addr))
00420     {
00421       ptrace (PT_SYSCALL, pid, (PTRACE_TYPE_ARG3) 0, 0);
00422       waitpid (pid, NULL, __WALL | __WNOTHREAD);
00423     }
00424 
00425   /* If the user has not provided an executable file, try to extract
00426      the image from inside the target process.  */
00427   if (!get_exec_file (0))
00428     spu_symbol_file_add_from_memory (fd);
00429 }
00430 
00431 /* Wait for child PTID to do something.  Return id of the child,
00432    minus_one_ptid in case of error; store status into *OURSTATUS.  */
00433 static ptid_t
00434 spu_child_wait (struct target_ops *ops,
00435                 ptid_t ptid, struct target_waitstatus *ourstatus, int options)
00436 {
00437   int save_errno;
00438   int status;
00439   pid_t pid;
00440 
00441   do
00442     {
00443       set_sigint_trap ();       /* Causes SIGINT to be passed on to the
00444                                    attached process.  */
00445 
00446       pid = waitpid (ptid_get_pid (ptid), &status, 0);
00447       if (pid == -1 && errno == ECHILD)
00448         /* Try again with __WCLONE to check cloned processes.  */
00449         pid = waitpid (ptid_get_pid (ptid), &status, __WCLONE);
00450 
00451       save_errno = errno;
00452 
00453       /* Make sure we don't report an event for the exit of the
00454          original program, if we've detached from it.  */
00455       if (pid != -1 && !WIFSTOPPED (status)
00456           && pid != ptid_get_pid (inferior_ptid))
00457         {
00458           pid = -1;
00459           save_errno = EINTR;
00460         }
00461 
00462       clear_sigint_trap ();
00463     }
00464   while (pid == -1 && save_errno == EINTR);
00465 
00466   if (pid == -1)
00467     {
00468       warning (_("Child process unexpectedly missing: %s"),
00469                safe_strerror (save_errno));
00470 
00471       /* Claim it exited with unknown signal.  */
00472       ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
00473       ourstatus->value.sig = GDB_SIGNAL_UNKNOWN;
00474       return inferior_ptid;
00475     }
00476 
00477   store_waitstatus (ourstatus, status);
00478   return pid_to_ptid (pid);
00479 }
00480 
00481 /* Override the fetch_inferior_register routine.  */
00482 static void
00483 spu_fetch_inferior_registers (struct target_ops *ops,
00484                               struct regcache *regcache, int regno)
00485 {
00486   int fd;
00487   ULONGEST addr;
00488 
00489   /* We must be stopped on a spu_run system call.  */
00490   if (!parse_spufs_run (&fd, &addr))
00491     return;
00492 
00493   /* The ID register holds the spufs file handle.  */
00494   if (regno == -1 || regno == SPU_ID_REGNUM)
00495     {
00496       struct gdbarch *gdbarch = get_regcache_arch (regcache);
00497       enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
00498       gdb_byte buf[4];
00499       store_unsigned_integer (buf, 4, byte_order, fd);
00500       regcache_raw_supply (regcache, SPU_ID_REGNUM, buf);
00501     }
00502 
00503   /* The NPC register is found at ADDR.  */
00504   if (regno == -1 || regno == SPU_PC_REGNUM)
00505     {
00506       gdb_byte buf[4];
00507       if (fetch_ppc_memory (addr, buf, 4) == 0)
00508         regcache_raw_supply (regcache, SPU_PC_REGNUM, buf);
00509     }
00510 
00511   /* The GPRs are found in the "regs" spufs file.  */
00512   if (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))
00513     {
00514       gdb_byte buf[16 * SPU_NUM_GPRS];
00515       char annex[32];
00516       int i;
00517 
00518       xsnprintf (annex, sizeof annex, "%d/regs", fd);
00519       if (spu_proc_xfer_spu (annex, buf, NULL, 0, sizeof buf) == sizeof buf)
00520         for (i = 0; i < SPU_NUM_GPRS; i++)
00521           regcache_raw_supply (regcache, i, buf + i*16);
00522     }
00523 }
00524 
00525 /* Override the store_inferior_register routine.  */
00526 static void
00527 spu_store_inferior_registers (struct target_ops *ops,
00528                               struct regcache *regcache, int regno)
00529 {
00530   int fd;
00531   ULONGEST addr;
00532 
00533   /* We must be stopped on a spu_run system call.  */
00534   if (!parse_spufs_run (&fd, &addr))
00535     return;
00536 
00537   /* The NPC register is found at ADDR.  */
00538   if (regno == -1 || regno == SPU_PC_REGNUM)
00539     {
00540       gdb_byte buf[4];
00541       regcache_raw_collect (regcache, SPU_PC_REGNUM, buf);
00542       store_ppc_memory (addr, buf, 4);
00543     }
00544 
00545   /* The GPRs are found in the "regs" spufs file.  */
00546   if (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))
00547     {
00548       gdb_byte buf[16 * SPU_NUM_GPRS];
00549       char annex[32];
00550       int i;
00551 
00552       for (i = 0; i < SPU_NUM_GPRS; i++)
00553         regcache_raw_collect (regcache, i, buf + i*16);
00554 
00555       xsnprintf (annex, sizeof annex, "%d/regs", fd);
00556       spu_proc_xfer_spu (annex, NULL, buf, 0, sizeof buf);
00557     }
00558 }
00559 
00560 /* Override the to_xfer_partial routine.  */
00561 static LONGEST 
00562 spu_xfer_partial (struct target_ops *ops,
00563                   enum target_object object, const char *annex,
00564                   gdb_byte *readbuf, const gdb_byte *writebuf,
00565                   ULONGEST offset, LONGEST len)
00566 {
00567   if (object == TARGET_OBJECT_SPU)
00568     return spu_proc_xfer_spu (annex, readbuf, writebuf, offset, len);
00569 
00570   if (object == TARGET_OBJECT_MEMORY)
00571     {
00572       int fd;
00573       ULONGEST addr;
00574       char mem_annex[32], lslr_annex[32];
00575       gdb_byte buf[32];
00576       ULONGEST lslr;
00577       LONGEST ret;
00578 
00579       /* We must be stopped on a spu_run system call.  */
00580       if (!parse_spufs_run (&fd, &addr))
00581         return 0;
00582 
00583       /* Use the "mem" spufs file to access SPU local store.  */
00584       xsnprintf (mem_annex, sizeof mem_annex, "%d/mem", fd);
00585       ret = spu_proc_xfer_spu (mem_annex, readbuf, writebuf, offset, len);
00586       if (ret > 0)
00587         return ret;
00588 
00589       /* SPU local store access wraps the address around at the
00590          local store limit.  We emulate this here.  To avoid needing
00591          an extra access to retrieve the LSLR, we only do that after
00592          trying the original address first, and getting end-of-file.  */
00593       xsnprintf (lslr_annex, sizeof lslr_annex, "%d/lslr", fd);
00594       memset (buf, 0, sizeof buf);
00595       if (spu_proc_xfer_spu (lslr_annex, buf, NULL, 0, sizeof buf) <= 0)
00596         return ret;
00597 
00598       lslr = strtoulst (buf, NULL, 16);
00599       return spu_proc_xfer_spu (mem_annex, readbuf, writebuf,
00600                                 offset & lslr, len);
00601     }
00602 
00603   return -1;
00604 }
00605 
00606 /* Override the to_can_use_hw_breakpoint routine.  */
00607 static int
00608 spu_can_use_hw_breakpoint (int type, int cnt, int othertype)
00609 {
00610   return 0;
00611 }
00612 
00613 
00614 /* Initialize SPU native target.  */
00615 void 
00616 _initialize_spu_nat (void)
00617 {
00618   /* Generic ptrace methods.  */
00619   struct target_ops *t;
00620   t = inf_ptrace_target ();
00621 
00622   /* Add SPU methods.  */
00623   t->to_post_attach = spu_child_post_attach;  
00624   t->to_post_startup_inferior = spu_child_post_startup_inferior;
00625   t->to_wait = spu_child_wait;
00626   t->to_fetch_registers = spu_fetch_inferior_registers;
00627   t->to_store_registers = spu_store_inferior_registers;
00628   t->to_xfer_partial = spu_xfer_partial;
00629   t->to_can_use_hw_breakpoint = spu_can_use_hw_breakpoint;
00630 
00631   /* Register SPU target.  */
00632   add_target (t);
00633 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines