/* SPU native-dependent code for GDB, the GNU debugger.
   Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.

   Contributed by Ulrich Weigand <uweigand@de.ibm.com>.

   This file is part of GDB.

   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 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   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, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "gdbcore.h"
#include "gdb_string.h"
#include "target.h"
#include "inferior.h"
#include "inf-ptrace.h"
#include "regcache.h"
#include "symfile.h"
#include "gdb_wait.h"
#include "gdbthread.h"

#include <sys/ptrace.h>
#include <asm/ptrace.h>
#include <sys/types.h>
#include <sys/param.h>

#include "spu-tdep.h"

/* PPU side system calls.  */
#define INSTR_SC	0x44000002
#define NR_spu_run	0x0116


/* Fetch PPU register REGNO.  */
static ULONGEST
fetch_ppc_register (int regno)
{
  PTRACE_TYPE_RET res;

  int tid = TIDGET (inferior_ptid);
  if (tid == 0)
    tid = PIDGET (inferior_ptid);

#ifndef __powerpc64__
  /* If running as a 32-bit process on a 64-bit system, we attempt
     to get the full 64-bit register content of the target process.
     If the PPC special ptrace call fails, we're on a 32-bit system;
     just fall through to the regular ptrace call in that case.  */
  {
    gdb_byte buf[8];

    errno = 0;
    ptrace (PPC_PTRACE_PEEKUSR_3264, tid,
	    (PTRACE_TYPE_ARG3) (regno * 8), buf);
    if (errno == 0)
      ptrace (PPC_PTRACE_PEEKUSR_3264, tid,
	      (PTRACE_TYPE_ARG3) (regno * 8 + 4), buf + 4);
    if (errno == 0)
      return (ULONGEST) *(uint64_t *)buf;
  }
#endif

  errno = 0;
  res = ptrace (PT_READ_U, tid,
	 	(PTRACE_TYPE_ARG3) (regno * sizeof (PTRACE_TYPE_RET)), 0);
  if (errno != 0)
    {
      char mess[128];
      xsnprintf (mess, sizeof mess, "reading PPC register #%d", regno);
      perror_with_name (_(mess));
    }

  return (ULONGEST) (unsigned long) res;
}

/* Fetch WORD from PPU memory at (aligned) MEMADDR in thread TID.  */
static int
fetch_ppc_memory_1 (int tid, ULONGEST memaddr, PTRACE_TYPE_RET *word)
{
  errno = 0;

#ifndef __powerpc64__
  if (memaddr >> 32)
    {
      uint64_t addr_8 = (uint64_t) memaddr;
      ptrace (PPC_PTRACE_PEEKTEXT_3264, tid, (PTRACE_TYPE_ARG3) &addr_8, word);
    }
  else
#endif
    *word = ptrace (PT_READ_I, tid, (PTRACE_TYPE_ARG3) (size_t) memaddr, 0);

  return errno;
}

/* Store WORD into PPU memory at (aligned) MEMADDR in thread TID.  */
static int
store_ppc_memory_1 (int tid, ULONGEST memaddr, PTRACE_TYPE_RET word)
{
  errno = 0;

#ifndef __powerpc64__
  if (memaddr >> 32)
    {
      uint64_t addr_8 = (uint64_t) memaddr;
      ptrace (PPC_PTRACE_POKEDATA_3264, tid, (PTRACE_TYPE_ARG3) &addr_8, word);
    }
  else
#endif
    ptrace (PT_WRITE_D, tid, (PTRACE_TYPE_ARG3) (size_t) memaddr, word);

  return errno;
}

/* Fetch LEN bytes of PPU memory at MEMADDR to MYADDR.  */
static int
fetch_ppc_memory (ULONGEST memaddr, gdb_byte *myaddr, int len)
{
  int i, 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;

  int tid = TIDGET (inferior_ptid);
  if (tid == 0)
    tid = PIDGET (inferior_ptid);

  buffer = (PTRACE_TYPE_RET *) alloca (count * sizeof (PTRACE_TYPE_RET));
  for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET))
    {
      ret = fetch_ppc_memory_1 (tid, addr, &buffer[i]);
      if (ret)
	return ret;
    }

  memcpy (myaddr,
	  (char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)),
	  len);

  return 0;
}

/* Store LEN bytes from MYADDR to PPU memory at MEMADDR.  */
static int
store_ppc_memory (ULONGEST memaddr, const gdb_byte *myaddr, int len)
{
  int i, 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;

  int tid = TIDGET (inferior_ptid);
  if (tid == 0)
    tid = PIDGET (inferior_ptid);

  buffer = (PTRACE_TYPE_RET *) alloca (count * sizeof (PTRACE_TYPE_RET));

  if (addr != memaddr || len < (int) sizeof (PTRACE_TYPE_RET))
    {
      ret = fetch_ppc_memory_1 (tid, addr, &buffer[0]);
      if (ret)
	return ret;
    }

  if (count > 1)
    {
      ret = fetch_ppc_memory_1 (tid, addr + (count - 1)
					       * sizeof (PTRACE_TYPE_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))
    {
      ret = store_ppc_memory_1 (tid, addr, buffer[i]);
      if (ret)
	return ret;
    }

  return 0;
}


/* If the PPU thread is currently stopped on a spu_run system call,
   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, ULONGEST *addr)
{
  gdb_byte buf[4];
  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)
    return 0;
  /* System call number should be NR_spu_run.  */
  if (fetch_ppc_register (0) != NR_spu_run)
    return 0;

  /* Register 3 contains fd, register 4 the NPC param pointer.  */
  *fd = fetch_ppc_register (34);  /* orig_gpr3 */
  *addr = fetch_ppc_register (4);
  return 1;
}


/* Copy LEN bytes at OFFSET in spufs file ANNEX into/from READBUF or WRITEBUF,
   using the /proc file system.  */
static LONGEST
spu_proc_xfer_spu (const char *annex, gdb_byte *readbuf,
		   const gdb_byte *writebuf,
		   ULONGEST offset, LONGEST len)
{
  char buf[128];
  int fd = 0;
  int ret = -1;
  int pid = PIDGET (inferior_ptid);

  if (!annex)
    return 0;

  xsnprintf (buf, sizeof buf, "/proc/%d/fd/%s", pid, annex);
  fd = open (buf, writebuf? O_WRONLY : O_RDONLY);
  if (fd <= 0)
    return -1;

  if (offset != 0
      && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
    {
      close (fd);
      return 0;
    }

  if (writebuf)
    ret = write (fd, writebuf, (size_t) len);
  else if (readbuf)
    ret = read (fd, readbuf, (size_t) len);

  close (fd);
  return ret;
}


/* Inferior memory should contain an SPE executable image at location ADDR.
   Allocate a BFD representing that executable.  Return NULL on error.  */

static void *
spu_bfd_iovec_open (struct bfd *nbfd, void *open_closure)
{
  return open_closure;
}

static int
spu_bfd_iovec_close (struct bfd *nbfd, void *stream)
{
  xfree (stream);
  return 1;
}

static file_ptr
spu_bfd_iovec_pread (struct bfd *abfd, void *stream, void *buf,
	             file_ptr nbytes, file_ptr offset)
{
  ULONGEST addr = *(ULONGEST *)stream;

  if (fetch_ppc_memory (addr + offset, buf, nbytes) != 0)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return -1;
    }

  return nbytes;
}

static int
spu_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb)
{
  /* We don't have an easy way of finding the size of embedded spu
     images.  We could parse the in-memory ELF header and section
     table to find the extent of the last section but that seems
     pointless when the size is needed only for checks of other
     parsed values in dbxread.c.  */
  sb->st_size = INT_MAX;
  return 0;
}

static bfd *
spu_bfd_open (ULONGEST addr)
{
  struct bfd *nbfd;
  asection *spu_name;

  ULONGEST *open_closure = xmalloc (sizeof (ULONGEST));
  *open_closure = addr;

  nbfd = bfd_openr_iovec (xstrdup ("<in-memory>"), "elf32-spu",
			  spu_bfd_iovec_open, open_closure,
			  spu_bfd_iovec_pread, spu_bfd_iovec_close,
			  spu_bfd_iovec_stat);
  if (!nbfd)
    return NULL;

  if (!bfd_check_format (nbfd, bfd_object))
    {
      bfd_close (nbfd);
      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;
}

/* INFERIOR_FD is a file handle passed by the inferior to the
   spu_run system call.  Assuming the SPE context was allocated
   by the libspe library, try to retrieve the main SPE executable
   file from its copy within the target process.  */
static void
spu_symbol_file_add_from_memory (int inferior_fd)
{
  ULONGEST addr;
  struct bfd *nbfd;

  char id[128];
  char annex[32];
  int len;

  /* Read object ID.  */
  xsnprintf (annex, sizeof annex, "%d/object-id", inferior_fd);
  len = spu_proc_xfer_spu (annex, id, NULL, 0, sizeof id);
  if (len <= 0 || len >= sizeof id)
    return;
  id[len] = 0;
  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, SYMFILE_VERBOSE | SYMFILE_MAINLINE,
                              NULL, 0);
}


/* Override the post_startup_inferior routine to continue running
   the inferior until the first spu_run system call.  */
static void
spu_child_post_startup_inferior (ptid_t ptid)
{
  int fd;
  ULONGEST addr;

  int tid = TIDGET (ptid);
  if (tid == 0)
    tid = PIDGET (ptid);
  
  while (!parse_spufs_run (&fd, &addr))
    {
      ptrace (PT_SYSCALL, tid, (PTRACE_TYPE_ARG3) 0, 0);
      waitpid (tid, NULL, __WALL | __WNOTHREAD);
    }
}

/* Override the post_attach routine to try load the SPE executable
   file image from its copy inside the target process.  */
static void
spu_child_post_attach (int pid)
{
  int fd;
  ULONGEST addr;

  /* Like child_post_startup_inferior, if we happened to attach to
     the inferior while it wasn't currently in spu_run, continue 
     running it until we get back there.  */
  while (!parse_spufs_run (&fd, &addr))
    {
      ptrace (PT_SYSCALL, pid, (PTRACE_TYPE_ARG3) 0, 0);
      waitpid (pid, NULL, __WALL | __WNOTHREAD);
    }

  /* If the user has not provided an executable file, try to extract
     the image from inside the target process.  */
  if (!get_exec_file (0))
    spu_symbol_file_add_from_memory (fd);
}

/* 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 (struct target_ops *ops,
		ptid_t ptid, struct target_waitstatus *ourstatus, int options)
{
  int save_errno;
  int status;
  pid_t pid;

  do
    {
      set_sigint_trap ();	/* Causes SIGINT to be passed on to the
				   attached process.  */

      pid = waitpid (PIDGET (ptid), &status, 0);
      if (pid == -1 && errno == ECHILD)
	/* Try again with __WCLONE to check cloned processes.  */
	pid = waitpid (PIDGET (ptid), &status, __WCLONE);

      save_errno = errno;

      /* Make sure we don't report an event for the exit of the
         original program, if we've detached from it.  */
      if (pid != -1 && !WIFSTOPPED (status) && pid != PIDGET (inferior_ptid))
	{
	  pid = -1;
	  save_errno = EINTR;
	}

      clear_sigint_trap ();
    }
  while (pid == -1 && save_errno == EINTR);

  if (pid == -1)
    {
      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 inferior_ptid;
    }

  store_waitstatus (ourstatus, status);
  return pid_to_ptid (pid);
}

/* Override the fetch_inferior_register routine.  */
static void
spu_fetch_inferior_registers (struct target_ops *ops,
			      struct regcache *regcache, int regno)
{
  int fd;
  ULONGEST addr;

  /* We must be stopped on a spu_run system call.  */
  if (!parse_spufs_run (&fd, &addr))
    return;

  /* The ID register holds the spufs file handle.  */
  if (regno == -1 || regno == SPU_ID_REGNUM)
    {
      char buf[4];
      store_unsigned_integer (buf, 4, fd);
      regcache_raw_supply (regcache, SPU_ID_REGNUM, buf);
    }

  /* The NPC register is found at ADDR.  */
  if (regno == -1 || regno == SPU_PC_REGNUM)
    {
      gdb_byte buf[4];
      if (fetch_ppc_memory (addr, buf, 4) == 0)
	regcache_raw_supply (regcache, SPU_PC_REGNUM, buf);
    }

  /* The GPRs are found in the "regs" spufs file.  */
  if (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))
    {
      gdb_byte buf[16 * SPU_NUM_GPRS];
      char annex[32];
      int i;

      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 (regcache, i, buf + i*16);
    }
}

/* Override the store_inferior_register routine.  */
static void
spu_store_inferior_registers (struct target_ops *ops,
			      struct regcache *regcache, int regno)
{
  int fd;
  ULONGEST addr;

  /* We must be stopped on a spu_run system call.  */
  if (!parse_spufs_run (&fd, &addr))
    return;

  /* The NPC register is found at ADDR.  */
  if (regno == -1 || regno == SPU_PC_REGNUM)
    {
      gdb_byte buf[4];
      regcache_raw_collect (regcache, SPU_PC_REGNUM, buf);
      store_ppc_memory (addr, buf, 4);
    }

  /* The GPRs are found in the "regs" spufs file.  */
  if (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))
    {
      gdb_byte buf[16 * SPU_NUM_GPRS];
      char annex[32];
      int i;

      for (i = 0; i < SPU_NUM_GPRS; i++)
	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);
    }
}

/* Override the to_xfer_partial routine.  */
static LONGEST 
spu_xfer_partial (struct target_ops *ops,
		  enum target_object object, const char *annex,
		  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;
      ULONGEST addr;
      char mem_annex[32];

      /* We must be stopped on a spu_run system call.  */
      if (!parse_spufs_run (&fd, &addr))
	return 0;

      /* 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);
    }

  return -1;
}

/* Override the to_can_use_hw_breakpoint routine.  */
static int
spu_can_use_hw_breakpoint (int type, int cnt, int othertype)
{
  return 0;
}


/* Initialize SPU native target.  */
void 
_initialize_spu_nat (void)
{
  /* Generic ptrace methods.  */
  struct target_ops *t;
  t = inf_ptrace_target ();

  /* Add SPU methods.  */
  t->to_post_attach = spu_child_post_attach;  
  t->to_post_startup_inferior = spu_child_post_startup_inferior;
  t->to_wait = spu_child_wait;
  t->to_fetch_registers = spu_fetch_inferior_registers;
  t->to_store_registers = spu_store_inferior_registers;
  t->to_xfer_partial = spu_xfer_partial;
  t->to_can_use_hw_breakpoint = spu_can_use_hw_breakpoint;

  /* Register SPU target.  */
  add_target (t);
}
