/* Machine-dependent hooks for the unix child process stratum.  This
   code is for the HP PA-RISC cpu.

   Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1998,
   1999, 2000, 2001 Free Software Foundation, Inc.

   Contributed by the Center for Software Science at the
   University of Utah (pa-gdb-bugs@cs.utah.edu).

   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 2 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, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

#include "defs.h"
#include "inferior.h"
#include "target.h"
#include "regcache.h"
#include <sys/ptrace.h>

/* Use an extra level of indirection for ptrace calls.
   This lets us breakpoint usefully on call_ptrace.   It also
   allows us to pass an extra argument to ptrace without
   using an ANSI-C specific macro.  */

#define ptrace call_ptrace

#if !defined (offsetof)
#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
#endif

/* U_REGS_OFFSET is the offset of the registers within the u area.  */
#if !defined (U_REGS_OFFSET)
#define U_REGS_OFFSET \
  ptrace (PT_READ_U, PIDGET (inferior_ptid), \
          (PTRACE_ARG3_TYPE) (offsetof (struct user, u_ar0)), 0) \
    - KERNEL_U_ADDR
#endif

/* Fetch one register.  */

static void
fetch_register (int regno)
{
  register unsigned int regaddr;
  char *buf = alloca (max_register_size (current_gdbarch));
  register int i;

  /* Offset of registers within the u area.  */
  unsigned int offset;

  offset = U_REGS_OFFSET;

  regaddr = register_addr (regno, offset);
  for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
    {
      errno = 0;
      *(int *) &buf[i] = ptrace (PT_RUREGS, PIDGET (inferior_ptid),
				 (PTRACE_ARG3_TYPE) regaddr, 0);
      regaddr += sizeof (int);
      if (errno != 0)
	{
	  /* Warning, not error, in case we are attached; sometimes the
	     kernel doesn't let us at the registers.  */
	  char *err = safe_strerror (errno);
	  char *msg = alloca (strlen (err) + 128);
	  sprintf (msg, "reading register %s: %s", REGISTER_NAME (regno), err);
	  warning (msg);
	  goto error_exit;
	}
    }
  supply_register (regno, buf);
error_exit:;
}

/* Fetch all registers, or just one, from the child process.  */

void
fetch_inferior_registers (int regno)
{
  if (regno == -1)
    for (regno = 0; regno < NUM_REGS; regno++)
      fetch_register (regno);
  else
    fetch_register (regno);
}

/* Store our register values back into the inferior.
   If REGNO is -1, do this for all registers.
   Otherwise, REGNO specifies which register (so we can save time).  */

void
store_inferior_registers (int regno)
{
  register unsigned int regaddr;
  char buf[80];
  register int i;
  unsigned int offset = U_REGS_OFFSET;
  int scratch;

  if (regno >= 0)
    {
      if (CANNOT_STORE_REGISTER (regno))
	return;
      regaddr = register_addr (regno, offset);
      errno = 0;
      if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM)
	{
	  scratch = *(int *) &deprecated_registers[REGISTER_BYTE (regno)] | 0x3;
	  ptrace (PT_WUREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr,
		  scratch);
	  if (errno != 0)
	    {
	      /* Error, even if attached.  Failing to write these two
	         registers is pretty serious.  */
	      sprintf (buf, "writing register number %d", regno);
	      perror_with_name (buf);
	    }
	}
      else
	for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
	  {
	    errno = 0;
	    ptrace (PT_WUREGS, PIDGET (inferior_ptid),
	            (PTRACE_ARG3_TYPE) regaddr,
		    *(int *) &deprecated_registers[REGISTER_BYTE (regno) + i]);
	    if (errno != 0)
	      {
		/* Warning, not error, in case we are attached; sometimes the
		   kernel doesn't let us at the registers.  */
		char *err = safe_strerror (errno);
		char *msg = alloca (strlen (err) + 128);
		sprintf (msg, "writing register %s: %s",
			 REGISTER_NAME (regno), err);
		warning (msg);
		return;
	      }
	    regaddr += sizeof (int);
	  }
    }
  else
    for (regno = 0; regno < NUM_REGS; regno++)
      store_inferior_registers (regno);
}

/* PT_PROT is specific to the PA BSD kernel and isn't documented
   anywhere (except here).  

   PT_PROT allows one to enable/disable the data memory break bit
   for pages of memory in an inferior process.  This bit is used
   to cause "Data memory break traps" to occur when the appropriate
   page is written to.

   The arguments are as follows:

   PT_PROT -- The ptrace action to perform.

   INFERIOR_PID -- The pid of the process who's page table entries
   will be modified.

   PT_ARGS -- The *address* of a 3 word block of memory which has
   additional information:

   word 0 -- The start address to watch.  This should be a page-aligned
   address.

   word 1 -- The ending address to watch.  Again, this should be a 
   page aligned address.

   word 2 -- Nonzero to enable the data memory break bit on the
   given address range or zero to disable the data memory break
   bit on the given address range.

   This call may fail if the given addresses are not valid in the inferior
   process.  This most often happens when restarting a program which
   has watchpoints inserted on heap or stack memory.  */

#define PT_PROT 21

int
hppa_set_watchpoint (int addr, int len, int flag)
{
  int pt_args[3];
  pt_args[0] = addr;
  pt_args[1] = addr + len;
  pt_args[2] = flag;

  /* Mask off the lower 12 bits since we want to work on a page basis.  */
  pt_args[0] >>= 12;
  pt_args[1] >>= 12;

  /* Rounding adjustments.  */
  pt_args[1] -= pt_args[0];
  pt_args[1]++;

  /* Put the lower 12 bits back as zero.  */
  pt_args[0] <<= 12;
  pt_args[1] <<= 12;

  /* Do it.  */
  return ptrace (PT_PROT, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) pt_args, 0);
}
