/* Native-dependent code for PA-RISC HP-UX.

   Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010
   Free Software Foundation, Inc.

   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 "inferior.h"
#include "regcache.h"
#include "target.h"

#include "gdb_assert.h"
#include <sys/ptrace.h>
#include <machine/save_state.h>

#ifdef HAVE_TTRACE
#include <sys/ttrace.h>
#endif

#include "hppa-tdep.h"
#include "inf-ptrace.h"
#include "inf-ttrace.h"

/* Non-zero if we should pretend not to be a runnable target.  */
int child_suppress_run = 0;

/* Return the offset of register REGNUM within `struct save_state'.
   The offset returns depends on the flags in the "flags" register and
   the register size (32-bit or 64-bit).  These are taken from
   REGCACHE.  */

LONGEST
hppa_hpux_save_state_offset (struct regcache *regcache, int regnum)
{
  LONGEST offset;

  if (regnum == HPPA_FLAGS_REGNUM)
    return ssoff (ss_flags);

  if (HPPA_R0_REGNUM < regnum && regnum < HPPA_FP0_REGNUM)
    {
      struct gdbarch *arch = get_regcache_arch (regcache);
      size_t size = register_size (arch, HPPA_R1_REGNUM);
      ULONGEST flags;

      gdb_assert (size == 4 || size == 8);

      regcache_cooked_read_unsigned (regcache, HPPA_FLAGS_REGNUM, &flags);
      if (flags & SS_WIDEREGS)
	offset = ssoff (ss_wide) + (8 - size) + (regnum - HPPA_R0_REGNUM) * 8;
      else
	offset = ssoff (ss_narrow) + (regnum - HPPA_R1_REGNUM) * 4;
    }
  else
    {
      struct gdbarch *arch = get_regcache_arch (regcache);
      size_t size = register_size (arch, HPPA_FP0_REGNUM);

      gdb_assert (size == 4 || size == 8);
      gdb_assert (regnum >= HPPA_FP0_REGNUM);
      offset = ssoff(ss_fpblock) + (regnum - HPPA_FP0_REGNUM) * size;
    }

  gdb_assert (offset < sizeof (save_state_t));
  return offset;
}

/* Just in case a future version of PA-RISC HP-UX won't have ptrace(2)
   at all.  */
#ifndef PTRACE_TYPE_RET
#define PTRACE_TYPE_RET void
#endif

static void
hppa_hpux_fetch_register (struct regcache *regcache, int regnum)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR addr;
  size_t size;
  PTRACE_TYPE_RET *buf;
  pid_t pid;
  int i;

  pid = ptid_get_pid (inferior_ptid);

  /* This isn't really an address, but ptrace thinks of it as one.  */
  addr = hppa_hpux_save_state_offset (regcache, regnum);
  size = register_size (gdbarch, regnum);

  gdb_assert (size == 4 || size == 8);
  buf = alloca (size);

#ifdef HAVE_TTRACE
  {
    lwpid_t lwp = ptid_get_lwp (inferior_ptid);

    if (ttrace (TT_LWP_RUREGS, pid, lwp, addr, size, (uintptr_t)buf) == -1)
      error (_("Couldn't read register %s (#%d): %s"),
	     gdbarch_register_name (gdbarch, regnum),
	     regnum, safe_strerror (errno));
  }
#else
  {
    int i;

    /* Read the register contents from the inferior a chuck at the time.  */
    for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
      {
	errno = 0;
	buf[i] = ptrace (PT_RUREGS, pid, (PTRACE_TYPE_ARG3) addr, 0, 0);
	if (errno != 0)
	  error (_("Couldn't read register %s (#%d): %s"),
		 gdbarch_register_name (gdbarch, regnum),
		 regnum, safe_strerror (errno));

	addr += sizeof (PTRACE_TYPE_RET);
      }
  }
#endif

  /* Take care with the "flags" register.  It's stored as an `int' in
     `struct save_state', even for 64-bit code.  */
  if (regnum == HPPA_FLAGS_REGNUM && size == 8)
    {
      ULONGEST flags;
      flags = extract_unsigned_integer ((gdb_byte *)buf, 4, byte_order);
      store_unsigned_integer ((gdb_byte *)buf, 8, byte_order, flags);
    }

  regcache_raw_supply (regcache, regnum, buf);
}

static void
hppa_hpux_fetch_inferior_registers (struct target_ops *ops,
				    struct regcache *regcache, int regnum)
{
  if (regnum == -1)
    for (regnum = 0;
	 regnum < gdbarch_num_regs (get_regcache_arch (regcache));
	 regnum++)
      hppa_hpux_fetch_register (regcache, regnum);
  else
    hppa_hpux_fetch_register (regcache, regnum);
}

/* Store register REGNUM into the inferior.  */

static void
hppa_hpux_store_register (struct regcache *regcache, int regnum)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR addr;
  size_t size;
  PTRACE_TYPE_RET *buf;
  pid_t pid;

  pid = ptid_get_pid (inferior_ptid);

  /* This isn't really an address, but ptrace thinks of it as one.  */
  addr = hppa_hpux_save_state_offset (regcache, regnum);
  size = register_size (gdbarch, regnum);

  gdb_assert (size == 4 || size == 8);
  buf = alloca (size);

  regcache_raw_collect (regcache, regnum, buf);

  /* Take care with the "flags" register.  It's stored as an `int' in
     `struct save_state', even for 64-bit code.  */
  if (regnum == HPPA_FLAGS_REGNUM && size == 8)
    {
      ULONGEST flags;
      flags = extract_unsigned_integer ((gdb_byte *)buf, 8, byte_order);
      store_unsigned_integer ((gdb_byte *)buf, 4, byte_order, flags);
      size = 4;
    }

#ifdef HAVE_TTRACE
  {
    lwpid_t lwp = ptid_get_lwp (inferior_ptid);

    if (ttrace (TT_LWP_WUREGS, pid, lwp, addr, size, (uintptr_t)buf) == -1)
      error (_("Couldn't write register %s (#%d): %s"),
	     gdbarch_register_name (gdbarch, regnum),
	     regnum, safe_strerror (errno));
  }
#else
  {
    int i;

    /* Write the register contents into the inferior a chunk at the time.  */
    for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
      {
	errno = 0;
	ptrace (PT_WUREGS, pid, (PTRACE_TYPE_ARG3) addr, buf[i], 0);
	if (errno != 0)
	  error (_("Couldn't write register %s (#%d): %s"),
		 gdbarch_register_name (gdbarch, regnum),
		 regnum, safe_strerror (errno));

	addr += sizeof (PTRACE_TYPE_RET);
      }
  }
#endif
}

/* Store register REGNUM back into the inferior.  If REGNUM is -1, do
   this for all registers (including the floating point registers).  */

static void
hppa_hpux_store_inferior_registers (struct target_ops *ops,
				    struct regcache *regcache, int regnum)
{
  if (regnum == -1)
    for (regnum = 0;
	 regnum < gdbarch_num_regs (get_regcache_arch (regcache));
	 regnum++)
      hppa_hpux_store_register (regcache, regnum);
  else
    hppa_hpux_store_register (regcache, regnum);
}

static int
hppa_hpux_child_can_run (void)
{
  /* This variable is controlled by modules that layer their own
     process structure atop that provided here.  The code in
     hpux-thread.c does this to support the HP-UX user-mode DCE
     threads.  */
  return !child_suppress_run;
}


/* Prevent warning from -Wmissing-prototypes.  */
void _initialize_hppa_hpux_nat (void);

void
_initialize_hppa_hpux_nat (void)
{
  struct target_ops *t;

#ifdef HAVE_TTRACE
  t = inf_ttrace_target ();
#else
  t = inf_ptrace_target ();
#endif

  t->to_fetch_registers = hppa_hpux_fetch_inferior_registers;
  t->to_store_registers = hppa_hpux_store_inferior_registers;
  t->to_can_run = hppa_hpux_child_can_run;

  add_target (t);
}
