GDB (API)
|
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 }