1/* SPU native-dependent code for GDB, the GNU debugger.
2   Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
3   Free Software Foundation, Inc.
4
5   Contributed by Ulrich Weigand <uweigand@de.ibm.com>.
6
7   This file is part of GDB.
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 3 of the License, or
12   (at your option) any later version.
13
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19   You should have received a copy of the GNU General Public License
20   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21
22#include "defs.h"
23#include "gdbcore.h"
24#include "gdb_string.h"
25#include "target.h"
26#include "inferior.h"
27#include "inf-ptrace.h"
28#include "regcache.h"
29#include "symfile.h"
30#include "gdb_wait.h"
31#include "gdbthread.h"
32
33#include <sys/ptrace.h>
34#include <asm/ptrace.h>
35#include <sys/types.h>
36#include <sys/param.h>
37
38#include "spu-tdep.h"
39
40/* PPU side system calls.  */
41#define INSTR_SC	0x44000002
42#define NR_spu_run	0x0116
43
44
45/* Fetch PPU register REGNO.  */
46static ULONGEST
47fetch_ppc_register (int regno)
48{
49  PTRACE_TYPE_RET res;
50
51  int tid = TIDGET (inferior_ptid);
52  if (tid == 0)
53    tid = PIDGET (inferior_ptid);
54
55#ifndef __powerpc64__
56  /* If running as a 32-bit process on a 64-bit system, we attempt
57     to get the full 64-bit register content of the target process.
58     If the PPC special ptrace call fails, we're on a 32-bit system;
59     just fall through to the regular ptrace call in that case.  */
60  {
61    gdb_byte buf[8];
62
63    errno = 0;
64    ptrace (PPC_PTRACE_PEEKUSR_3264, tid,
65	    (PTRACE_TYPE_ARG3) (regno * 8), buf);
66    if (errno == 0)
67      ptrace (PPC_PTRACE_PEEKUSR_3264, tid,
68	      (PTRACE_TYPE_ARG3) (regno * 8 + 4), buf + 4);
69    if (errno == 0)
70      return (ULONGEST) *(uint64_t *)buf;
71  }
72#endif
73
74  errno = 0;
75  res = ptrace (PT_READ_U, tid,
76	 	(PTRACE_TYPE_ARG3) (regno * sizeof (PTRACE_TYPE_RET)), 0);
77  if (errno != 0)
78    {
79      char mess[128];
80      xsnprintf (mess, sizeof mess, "reading PPC register #%d", regno);
81      perror_with_name (_(mess));
82    }
83
84  return (ULONGEST) (unsigned long) res;
85}
86
87/* Fetch WORD from PPU memory at (aligned) MEMADDR in thread TID.  */
88static int
89fetch_ppc_memory_1 (int tid, ULONGEST memaddr, PTRACE_TYPE_RET *word)
90{
91  errno = 0;
92
93#ifndef __powerpc64__
94  if (memaddr >> 32)
95    {
96      uint64_t addr_8 = (uint64_t) memaddr;
97      ptrace (PPC_PTRACE_PEEKTEXT_3264, tid, (PTRACE_TYPE_ARG3) &addr_8, word);
98    }
99  else
100#endif
101    *word = ptrace (PT_READ_I, tid, (PTRACE_TYPE_ARG3) (size_t) memaddr, 0);
102
103  return errno;
104}
105
106/* Store WORD into PPU memory at (aligned) MEMADDR in thread TID.  */
107static int
108store_ppc_memory_1 (int tid, ULONGEST memaddr, PTRACE_TYPE_RET word)
109{
110  errno = 0;
111
112#ifndef __powerpc64__
113  if (memaddr >> 32)
114    {
115      uint64_t addr_8 = (uint64_t) memaddr;
116      ptrace (PPC_PTRACE_POKEDATA_3264, tid, (PTRACE_TYPE_ARG3) &addr_8, word);
117    }
118  else
119#endif
120    ptrace (PT_WRITE_D, tid, (PTRACE_TYPE_ARG3) (size_t) memaddr, word);
121
122  return errno;
123}
124
125/* Fetch LEN bytes of PPU memory at MEMADDR to MYADDR.  */
126static int
127fetch_ppc_memory (ULONGEST memaddr, gdb_byte *myaddr, int len)
128{
129  int i, ret;
130
131  ULONGEST addr = memaddr & -(ULONGEST) sizeof (PTRACE_TYPE_RET);
132  int count = ((((memaddr + len) - addr) + sizeof (PTRACE_TYPE_RET) - 1)
133	       / sizeof (PTRACE_TYPE_RET));
134  PTRACE_TYPE_RET *buffer;
135
136  int tid = TIDGET (inferior_ptid);
137  if (tid == 0)
138    tid = PIDGET (inferior_ptid);
139
140  buffer = (PTRACE_TYPE_RET *) alloca (count * sizeof (PTRACE_TYPE_RET));
141  for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET))
142    {
143      ret = fetch_ppc_memory_1 (tid, addr, &buffer[i]);
144      if (ret)
145	return ret;
146    }
147
148  memcpy (myaddr,
149	  (char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)),
150	  len);
151
152  return 0;
153}
154
155/* Store LEN bytes from MYADDR to PPU memory at MEMADDR.  */
156static int
157store_ppc_memory (ULONGEST memaddr, const gdb_byte *myaddr, int len)
158{
159  int i, ret;
160
161  ULONGEST addr = memaddr & -(ULONGEST) sizeof (PTRACE_TYPE_RET);
162  int count = ((((memaddr + len) - addr) + sizeof (PTRACE_TYPE_RET) - 1)
163	       / sizeof (PTRACE_TYPE_RET));
164  PTRACE_TYPE_RET *buffer;
165
166  int tid = TIDGET (inferior_ptid);
167  if (tid == 0)
168    tid = PIDGET (inferior_ptid);
169
170  buffer = (PTRACE_TYPE_RET *) alloca (count * sizeof (PTRACE_TYPE_RET));
171
172  if (addr != memaddr || len < (int) sizeof (PTRACE_TYPE_RET))
173    {
174      ret = fetch_ppc_memory_1 (tid, addr, &buffer[0]);
175      if (ret)
176	return ret;
177    }
178
179  if (count > 1)
180    {
181      ret = fetch_ppc_memory_1 (tid, addr + (count - 1)
182					       * sizeof (PTRACE_TYPE_RET),
183				&buffer[count - 1]);
184      if (ret)
185	return ret;
186    }
187
188  memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)),
189          myaddr, len);
190
191  for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET))
192    {
193      ret = store_ppc_memory_1 (tid, addr, buffer[i]);
194      if (ret)
195	return ret;
196    }
197
198  return 0;
199}
200
201
202/* If the PPU thread is currently stopped on a spu_run system call,
203   return to FD and ADDR the file handle and NPC parameter address
204   used with the system call.  Return non-zero if successful.  */
205static int
206parse_spufs_run (int *fd, ULONGEST *addr)
207{
208  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
209  gdb_byte buf[4];
210  ULONGEST pc = fetch_ppc_register (32);  /* nip */
211
212  /* Fetch instruction preceding current NIP.  */
213  if (fetch_ppc_memory (pc-4, buf, 4) != 0)
214    return 0;
215  /* It should be a "sc" instruction.  */
216  if (extract_unsigned_integer (buf, 4, byte_order) != INSTR_SC)
217    return 0;
218  /* System call number should be NR_spu_run.  */
219  if (fetch_ppc_register (0) != NR_spu_run)
220    return 0;
221
222  /* Register 3 contains fd, register 4 the NPC param pointer.  */
223  *fd = fetch_ppc_register (34);  /* orig_gpr3 */
224  *addr = fetch_ppc_register (4);
225  return 1;
226}
227
228
229/* Copy LEN bytes at OFFSET in spufs file ANNEX into/from READBUF or WRITEBUF,
230   using the /proc file system.  */
231static LONGEST
232spu_proc_xfer_spu (const char *annex, gdb_byte *readbuf,
233		   const gdb_byte *writebuf,
234		   ULONGEST offset, LONGEST len)
235{
236  char buf[128];
237  int fd = 0;
238  int ret = -1;
239  int pid = PIDGET (inferior_ptid);
240
241  if (!annex)
242    return 0;
243
244  xsnprintf (buf, sizeof buf, "/proc/%d/fd/%s", pid, annex);
245  fd = open (buf, writebuf? O_WRONLY : O_RDONLY);
246  if (fd <= 0)
247    return -1;
248
249  if (offset != 0
250      && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
251    {
252      close (fd);
253      return 0;
254    }
255
256  if (writebuf)
257    ret = write (fd, writebuf, (size_t) len);
258  else if (readbuf)
259    ret = read (fd, readbuf, (size_t) len);
260
261  close (fd);
262  return ret;
263}
264
265
266/* Inferior memory should contain an SPE executable image at location ADDR.
267   Allocate a BFD representing that executable.  Return NULL on error.  */
268
269static void *
270spu_bfd_iovec_open (struct bfd *nbfd, void *open_closure)
271{
272  return open_closure;
273}
274
275static int
276spu_bfd_iovec_close (struct bfd *nbfd, void *stream)
277{
278  xfree (stream);
279  return 1;
280}
281
282static file_ptr
283spu_bfd_iovec_pread (struct bfd *abfd, void *stream, void *buf,
284	             file_ptr nbytes, file_ptr offset)
285{
286  ULONGEST addr = *(ULONGEST *)stream;
287
288  if (fetch_ppc_memory (addr + offset, buf, nbytes) != 0)
289    {
290      bfd_set_error (bfd_error_invalid_operation);
291      return -1;
292    }
293
294  return nbytes;
295}
296
297static int
298spu_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb)
299{
300  /* We don't have an easy way of finding the size of embedded spu
301     images.  We could parse the in-memory ELF header and section
302     table to find the extent of the last section but that seems
303     pointless when the size is needed only for checks of other
304     parsed values in dbxread.c.  */
305  sb->st_size = INT_MAX;
306  return 0;
307}
308
309static bfd *
310spu_bfd_open (ULONGEST addr)
311{
312  struct bfd *nbfd;
313  asection *spu_name;
314
315  ULONGEST *open_closure = xmalloc (sizeof (ULONGEST));
316  *open_closure = addr;
317
318  nbfd = bfd_openr_iovec (xstrdup ("<in-memory>"), "elf32-spu",
319			  spu_bfd_iovec_open, open_closure,
320			  spu_bfd_iovec_pread, spu_bfd_iovec_close,
321			  spu_bfd_iovec_stat);
322  if (!nbfd)
323    return NULL;
324
325  if (!bfd_check_format (nbfd, bfd_object))
326    {
327      bfd_close (nbfd);
328      return NULL;
329    }
330
331  /* Retrieve SPU name note and update BFD name.  */
332  spu_name = bfd_get_section_by_name (nbfd, ".note.spu_name");
333  if (spu_name)
334    {
335      int sect_size = bfd_section_size (nbfd, spu_name);
336      if (sect_size > 20)
337	{
338	  char *buf = alloca (sect_size - 20 + 1);
339	  bfd_get_section_contents (nbfd, spu_name, buf, 20, sect_size - 20);
340	  buf[sect_size - 20] = '\0';
341
342	  xfree ((char *)nbfd->filename);
343	  nbfd->filename = xstrdup (buf);
344	}
345    }
346
347  return nbfd;
348}
349
350/* INFERIOR_FD is a file handle passed by the inferior to the
351   spu_run system call.  Assuming the SPE context was allocated
352   by the libspe library, try to retrieve the main SPE executable
353   file from its copy within the target process.  */
354static void
355spu_symbol_file_add_from_memory (int inferior_fd)
356{
357  ULONGEST addr;
358  struct bfd *nbfd;
359
360  char id[128];
361  char annex[32];
362  int len;
363
364  /* Read object ID.  */
365  xsnprintf (annex, sizeof annex, "%d/object-id", inferior_fd);
366  len = spu_proc_xfer_spu (annex, id, NULL, 0, sizeof id);
367  if (len <= 0 || len >= sizeof id)
368    return;
369  id[len] = 0;
370  addr = strtoulst (id, NULL, 16);
371  if (!addr)
372    return;
373
374  /* Open BFD representing SPE executable and read its symbols.  */
375  nbfd = spu_bfd_open (addr);
376  if (nbfd)
377    symbol_file_add_from_bfd (nbfd, SYMFILE_VERBOSE | SYMFILE_MAINLINE,
378                              NULL, 0);
379}
380
381
382/* Override the post_startup_inferior routine to continue running
383   the inferior until the first spu_run system call.  */
384static void
385spu_child_post_startup_inferior (ptid_t ptid)
386{
387  int fd;
388  ULONGEST addr;
389
390  int tid = TIDGET (ptid);
391  if (tid == 0)
392    tid = PIDGET (ptid);
393
394  while (!parse_spufs_run (&fd, &addr))
395    {
396      ptrace (PT_SYSCALL, tid, (PTRACE_TYPE_ARG3) 0, 0);
397      waitpid (tid, NULL, __WALL | __WNOTHREAD);
398    }
399}
400
401/* Override the post_attach routine to try load the SPE executable
402   file image from its copy inside the target process.  */
403static void
404spu_child_post_attach (int pid)
405{
406  int fd;
407  ULONGEST addr;
408
409  /* Like child_post_startup_inferior, if we happened to attach to
410     the inferior while it wasn't currently in spu_run, continue
411     running it until we get back there.  */
412  while (!parse_spufs_run (&fd, &addr))
413    {
414      ptrace (PT_SYSCALL, pid, (PTRACE_TYPE_ARG3) 0, 0);
415      waitpid (pid, NULL, __WALL | __WNOTHREAD);
416    }
417
418  /* If the user has not provided an executable file, try to extract
419     the image from inside the target process.  */
420  if (!get_exec_file (0))
421    spu_symbol_file_add_from_memory (fd);
422}
423
424/* Wait for child PTID to do something.  Return id of the child,
425   minus_one_ptid in case of error; store status into *OURSTATUS.  */
426static ptid_t
427spu_child_wait (struct target_ops *ops,
428		ptid_t ptid, struct target_waitstatus *ourstatus, int options)
429{
430  int save_errno;
431  int status;
432  pid_t pid;
433
434  do
435    {
436      set_sigint_trap ();	/* Causes SIGINT to be passed on to the
437				   attached process.  */
438
439      pid = waitpid (PIDGET (ptid), &status, 0);
440      if (pid == -1 && errno == ECHILD)
441	/* Try again with __WCLONE to check cloned processes.  */
442	pid = waitpid (PIDGET (ptid), &status, __WCLONE);
443
444      save_errno = errno;
445
446      /* Make sure we don't report an event for the exit of the
447         original program, if we've detached from it.  */
448      if (pid != -1 && !WIFSTOPPED (status) && pid != PIDGET (inferior_ptid))
449	{
450	  pid = -1;
451	  save_errno = EINTR;
452	}
453
454      clear_sigint_trap ();
455    }
456  while (pid == -1 && save_errno == EINTR);
457
458  if (pid == -1)
459    {
460      warning (_("Child process unexpectedly missing: %s"),
461	       safe_strerror (save_errno));
462
463      /* Claim it exited with unknown signal.  */
464      ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
465      ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
466      return inferior_ptid;
467    }
468
469  store_waitstatus (ourstatus, status);
470  return pid_to_ptid (pid);
471}
472
473/* Override the fetch_inferior_register routine.  */
474static void
475spu_fetch_inferior_registers (struct target_ops *ops,
476			      struct regcache *regcache, int regno)
477{
478  int fd;
479  ULONGEST addr;
480
481  /* We must be stopped on a spu_run system call.  */
482  if (!parse_spufs_run (&fd, &addr))
483    return;
484
485  /* The ID register holds the spufs file handle.  */
486  if (regno == -1 || regno == SPU_ID_REGNUM)
487    {
488      struct gdbarch *gdbarch = get_regcache_arch (regcache);
489      enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
490      char buf[4];
491      store_unsigned_integer (buf, 4, byte_order, fd);
492      regcache_raw_supply (regcache, SPU_ID_REGNUM, buf);
493    }
494
495  /* The NPC register is found at ADDR.  */
496  if (regno == -1 || regno == SPU_PC_REGNUM)
497    {
498      gdb_byte buf[4];
499      if (fetch_ppc_memory (addr, buf, 4) == 0)
500	regcache_raw_supply (regcache, SPU_PC_REGNUM, buf);
501    }
502
503  /* The GPRs are found in the "regs" spufs file.  */
504  if (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))
505    {
506      gdb_byte buf[16 * SPU_NUM_GPRS];
507      char annex[32];
508      int i;
509
510      xsnprintf (annex, sizeof annex, "%d/regs", fd);
511      if (spu_proc_xfer_spu (annex, buf, NULL, 0, sizeof buf) == sizeof buf)
512	for (i = 0; i < SPU_NUM_GPRS; i++)
513	  regcache_raw_supply (regcache, i, buf + i*16);
514    }
515}
516
517/* Override the store_inferior_register routine.  */
518static void
519spu_store_inferior_registers (struct target_ops *ops,
520			      struct regcache *regcache, int regno)
521{
522  int fd;
523  ULONGEST addr;
524
525  /* We must be stopped on a spu_run system call.  */
526  if (!parse_spufs_run (&fd, &addr))
527    return;
528
529  /* The NPC register is found at ADDR.  */
530  if (regno == -1 || regno == SPU_PC_REGNUM)
531    {
532      gdb_byte buf[4];
533      regcache_raw_collect (regcache, SPU_PC_REGNUM, buf);
534      store_ppc_memory (addr, buf, 4);
535    }
536
537  /* The GPRs are found in the "regs" spufs file.  */
538  if (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))
539    {
540      gdb_byte buf[16 * SPU_NUM_GPRS];
541      char annex[32];
542      int i;
543
544      for (i = 0; i < SPU_NUM_GPRS; i++)
545	regcache_raw_collect (regcache, i, buf + i*16);
546
547      xsnprintf (annex, sizeof annex, "%d/regs", fd);
548      spu_proc_xfer_spu (annex, NULL, buf, 0, sizeof buf);
549    }
550}
551
552/* Override the to_xfer_partial routine.  */
553static LONGEST
554spu_xfer_partial (struct target_ops *ops,
555		  enum target_object object, const char *annex,
556		  gdb_byte *readbuf, const gdb_byte *writebuf,
557		  ULONGEST offset, LONGEST len)
558{
559  if (object == TARGET_OBJECT_SPU)
560    return spu_proc_xfer_spu (annex, readbuf, writebuf, offset, len);
561
562  if (object == TARGET_OBJECT_MEMORY)
563    {
564      int fd;
565      ULONGEST addr;
566      char mem_annex[32], lslr_annex[32];
567      gdb_byte buf[32];
568      ULONGEST lslr;
569      LONGEST ret;
570
571      /* We must be stopped on a spu_run system call.  */
572      if (!parse_spufs_run (&fd, &addr))
573	return 0;
574
575      /* Use the "mem" spufs file to access SPU local store.  */
576      xsnprintf (mem_annex, sizeof mem_annex, "%d/mem", fd);
577      ret = spu_proc_xfer_spu (mem_annex, readbuf, writebuf, offset, len);
578      if (ret > 0)
579	return ret;
580
581      /* SPU local store access wraps the address around at the
582	 local store limit.  We emulate this here.  To avoid needing
583	 an extra access to retrieve the LSLR, we only do that after
584	 trying the original address first, and getting end-of-file.  */
585      xsnprintf (lslr_annex, sizeof lslr_annex, "%d/lslr", fd);
586      memset (buf, 0, sizeof buf);
587      if (spu_proc_xfer_spu (lslr_annex, buf, NULL, 0, sizeof buf) <= 0)
588	return ret;
589
590      lslr = strtoulst (buf, NULL, 16);
591      return spu_proc_xfer_spu (mem_annex, readbuf, writebuf,
592				offset & lslr, len);
593    }
594
595  return -1;
596}
597
598/* Override the to_can_use_hw_breakpoint routine.  */
599static int
600spu_can_use_hw_breakpoint (int type, int cnt, int othertype)
601{
602  return 0;
603}
604
605
606/* Initialize SPU native target.  */
607void
608_initialize_spu_nat (void)
609{
610  /* Generic ptrace methods.  */
611  struct target_ops *t;
612  t = inf_ptrace_target ();
613
614  /* Add SPU methods.  */
615  t->to_post_attach = spu_child_post_attach;
616  t->to_post_startup_inferior = spu_child_post_startup_inferior;
617  t->to_wait = spu_child_wait;
618  t->to_fetch_registers = spu_fetch_inferior_registers;
619  t->to_store_registers = spu_store_inferior_registers;
620  t->to_xfer_partial = spu_xfer_partial;
621  t->to_can_use_hw_breakpoint = spu_can_use_hw_breakpoint;
622
623  /* Register SPU target.  */
624  add_target (t);
625}
626