/* Acorn Risc Machine host machine support.
   Copyright (C) 1988, 1989, 1991 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 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 "frame.h"
#include "inferior.h"
#include "opcode/arm.h"

#include <sys/param.h>
#include <sys/dir.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/ptrace.h>
#include <machine/reg.h>

#define N_TXTADDR(hdr) 0x8000
#define N_DATADDR(hdr) (hdr.a_text + 0x8000)

#include "gdbcore.h"

#include <sys/user.h>		/* After a.out.h  */
#include <sys/file.h>
#include "gdb_stat.h"

#include <errno.h>

void
fetch_inferior_registers (regno)
     int regno;			/* Original value discarded */
{
  register unsigned int regaddr;
  char buf[MAX_REGISTER_RAW_SIZE];
  register int i;

  struct user u;
  unsigned int offset = (char *) &u.u_ar0 - (char *) &u;
  offset = ptrace (PT_READ_U, inferior_pid, (PTRACE_ARG3_TYPE) offset, 0)
    - KERNEL_U_ADDR;

  registers_fetched ();

  for (regno = 0; regno < 16; regno++)
    {
      regaddr = offset + regno * 4;
      *(int *) &buf[0] = ptrace (PT_READ_U, inferior_pid,
				 (PTRACE_ARG3_TYPE) regaddr, 0);
      if (regno == PC_REGNUM)
	*(int *) &buf[0] = GET_PC_PART (*(int *) &buf[0]);
      supply_register (regno, buf);
    }
  *(int *) &buf[0] = ptrace (PT_READ_U, inferior_pid,
			     (PTRACE_ARG3_TYPE) (offset + PC * 4), 0);
  supply_register (PS_REGNUM, buf);	/* set virtual register ps same as pc */

  /* read the floating point registers */
  offset = (char *) &u.u_fp_regs - (char *) &u;
  *(int *) buf = ptrace (PT_READ_U, inferior_pid, (PTRACE_ARG3_TYPE) offset, 0);
  supply_register (FPS_REGNUM, buf);
  for (regno = 16; regno < 24; regno++)
    {
      regaddr = offset + 4 + 12 * (regno - 16);
      for (i = 0; i < 12; i += sizeof (int))
	 *(int *) &buf[i] = ptrace (PT_READ_U, inferior_pid,
				      (PTRACE_ARG3_TYPE) (regaddr + i), 0);
      supply_register (regno, buf);
    }
}

/* 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 (regno)
     int regno;
{
  register unsigned int regaddr;
  char buf[80];

  struct user u;
  unsigned long value;
  unsigned int offset = (char *) &u.u_ar0 - (char *) &u;
  offset = ptrace (PT_READ_U, inferior_pid, (PTRACE_ARG3_TYPE) offset, 0)
    - KERNEL_U_ADDR;

  if (regno >= 0)
    {
      if (regno >= 16)
	return;
      regaddr = offset + 4 * regno;
      errno = 0;
      value = read_register (regno);
      if (regno == PC_REGNUM)
	value = SET_PC_PART (read_register (PS_REGNUM), value);
      ptrace (PT_WRITE_U, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, value);
      if (errno != 0)
	{
	  sprintf (buf, "writing register number %d", regno);
	  perror_with_name (buf);
	}
    }
  else
    for (regno = 0; regno < 15; regno++)
      {
	regaddr = offset + regno * 4;
	errno = 0;
	value = read_register (regno);
	if (regno == PC_REGNUM)
	  value = SET_PC_PART (read_register (PS_REGNUM), value);
	ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, value);
	if (errno != 0)
	  {
	    sprintf (buf, "writing all regs, number %d", regno);
	    perror_with_name (buf);
	  }
      }
}

/* Work with core dump and executable files, for GDB. 
   This code would be in corefile.c if it weren't machine-dependent. */

/* Structure to describe the chain of shared libraries used
   by the execfile.
   e.g. prog shares Xt which shares X11 which shares c. */

struct shared_library
{
  struct exec_header header;
  char name[SHLIBLEN];
  CORE_ADDR text_start;		/* CORE_ADDR of 1st byte of text, this file */
  long data_offset;		/* offset of data section in file */
  int chan;			/* file descriptor for the file */
  struct shared_library *shares;	/* library this one shares */
};
static struct shared_library *shlib = 0;

/* Hook for `exec_file_command' command to call.  */

extern void (*exec_file_display_hook) ();

static CORE_ADDR unshared_text_start;

/* extended header from exec file (for shared library info) */

static struct exec_header exec_header;

void
core_file_command (filename, from_tty)
     char *filename;
     int from_tty;
{
  int val;

  /* Discard all vestiges of any previous core file
     and mark data and stack spaces as empty.  */

  if (corefile)
    free (corefile);
  corefile = 0;

  if (corechan >= 0)
    close (corechan);
  corechan = -1;

  data_start = 0;
  data_end = 0;
  stack_start = STACK_END_ADDR;
  stack_end = STACK_END_ADDR;

  /* Now, if a new core file was specified, open it and digest it.  */

  if (filename)
    {
      filename = tilde_expand (filename);
      make_cleanup (free, filename);

      if (have_inferior_p ())
	error ("To look at a core file, you must kill the program with \"kill\".");
      corechan = open (filename, O_RDONLY, 0);
      if (corechan < 0)
	perror_with_name (filename);
      /* 4.2-style (and perhaps also sysV-style) core dump file.  */
      {
	struct user u;

	unsigned int reg_offset, fp_reg_offset;

	val = myread (corechan, &u, sizeof u);
	if (val < 0)
	  perror_with_name ("Not a core file: reading upage");
	if (val != sizeof u)
	  error ("Not a core file: could only read %d bytes", val);

	/* We are depending on exec_file_command having been called
	   previously to set exec_data_start.  Since the executable
	   and the core file share the same text segment, the address
	   of the data segment will be the same in both.  */
	data_start = exec_data_start;

	data_end = data_start + NBPG * u.u_dsize;
	stack_start = stack_end - NBPG * u.u_ssize;
	data_offset = NBPG * UPAGES;
	stack_offset = NBPG * (UPAGES + u.u_dsize);

	/* Some machines put an absolute address in here and some put
	   the offset in the upage of the regs.  */
	reg_offset = (int) u.u_ar0;
	if (reg_offset > NBPG * UPAGES)
	  reg_offset -= KERNEL_U_ADDR;
	fp_reg_offset = (char *) &u.u_fp_regs - (char *) &u;

	/* I don't know where to find this info.
	   So, for now, mark it as not available.  */
	N_SET_MAGIC (core_aouthdr, 0);

	/* Read the register values out of the core file and store
	   them where `read_register' will find them.  */

	{
	  register int regno;

	  for (regno = 0; regno < NUM_REGS; regno++)
	    {
	      char buf[MAX_REGISTER_RAW_SIZE];

	      if (regno < 16)
		val = lseek (corechan, reg_offset + 4 * regno, 0);
	      else if (regno < 24)
		val = lseek (corechan, fp_reg_offset + 4 + 12 * (regno - 24), 0);
	      else if (regno == 24)
		val = lseek (corechan, fp_reg_offset, 0);
	      else if (regno == 25)
		val = lseek (corechan, reg_offset + 4 * PC, 0);
	      if (val < 0
		  || (val = myread (corechan, buf, sizeof buf)) < 0)
		{
		  char *buffer = (char *) alloca (strlen (REGISTER_NAME (regno))
						  + 30);
		  strcpy (buffer, "Reading register ");
		  strcat (buffer, REGISTER_NAME (regno));

		  perror_with_name (buffer);
		}

	      if (regno == PC_REGNUM)
		*(int *) buf = GET_PC_PART (*(int *) buf);
	      supply_register (regno, buf);
	    }
	}
      }
      if (filename[0] == '/')
	corefile = savestring (filename, strlen (filename));
      else
	{
	  corefile = concat (current_directory, "/", filename, NULL);
	}

      flush_cached_frames ();
      select_frame (get_current_frame (), 0);
      validate_files ();
    }
  else if (from_tty)
    printf ("No core file now.\n");
}

#if 0
/* Work with core dump and executable files, for GDB. 
   This code would be in corefile.c if it weren't machine-dependent. */

/* Structure to describe the chain of shared libraries used
   by the execfile.
   e.g. prog shares Xt which shares X11 which shares c. */

struct shared_library
{
  struct exec_header header;
  char name[SHLIBLEN];
  CORE_ADDR text_start;		/* CORE_ADDR of 1st byte of text, this file */
  long data_offset;		/* offset of data section in file */
  int chan;			/* file descriptor for the file */
  struct shared_library *shares;	/* library this one shares */
};
static struct shared_library *shlib = 0;

/* Hook for `exec_file_command' command to call.  */

extern void (*exec_file_display_hook) ();

static CORE_ADDR unshared_text_start;

/* extended header from exec file (for shared library info) */

static struct exec_header exec_header;

void
exec_file_command (filename, from_tty)
     char *filename;
     int from_tty;
{
  int val;

  /* Eliminate all traces of old exec file.
     Mark text segment as empty.  */

  if (execfile)
    free (execfile);
  execfile = 0;
  data_start = 0;
  data_end -= exec_data_start;
  text_start = 0;
  unshared_text_start = 0;
  text_end = 0;
  exec_data_start = 0;
  exec_data_end = 0;
  if (execchan >= 0)
    close (execchan);
  execchan = -1;
  if (shlib)
    {
      close_shared_library (shlib);
      shlib = 0;
    }

  /* Now open and digest the file the user requested, if any.  */

  if (filename)
    {
      filename = tilde_expand (filename);
      make_cleanup (free, filename);

      execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
			&execfile);
      if (execchan < 0)
	perror_with_name (filename);

      {
	struct stat st_exec;

#ifdef HEADER_SEEK_FD
	HEADER_SEEK_FD (execchan);
#endif

	val = myread (execchan, &exec_header, sizeof exec_header);
	exec_aouthdr = exec_header.a_exec;

	if (val < 0)
	  perror_with_name (filename);

	text_start = 0x8000;

	/* Look for shared library if needed */
	if (exec_header.a_exec.a_magic & MF_USES_SL)
	  shlib = open_shared_library (exec_header.a_shlibname, text_start);

	text_offset = N_TXTOFF (exec_aouthdr);
	exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text;

	if (shlib)
	  {
	    unshared_text_start = shared_text_end (shlib) & ~0x7fff;
	    stack_start = shlib->header.a_exec.a_sldatabase;
	    stack_end = STACK_END_ADDR;
	  }
	else
	  unshared_text_start = 0x8000;
	text_end = unshared_text_start + exec_aouthdr.a_text;

	exec_data_start = unshared_text_start + exec_aouthdr.a_text;
	exec_data_end = exec_data_start + exec_aouthdr.a_data;

	data_start = exec_data_start;
	data_end += exec_data_start;

	fstat (execchan, &st_exec);
	exec_mtime = st_exec.st_mtime;
      }

      validate_files ();
    }
  else if (from_tty)
    printf ("No executable file now.\n");

  /* Tell display code (if any) about the changed file name.  */
  if (exec_file_display_hook)
    (*exec_file_display_hook) (filename);
}
#endif

#if 0
/* Read from the program's memory (except for inferior processes).
   This function is misnamed, since it only reads, never writes; and
   since it will use the core file and/or executable file as necessary.

   It should be extended to write as well as read, FIXME, for patching files.

   Return 0 if address could be read, EIO if addresss out of bounds.  */

int
xfer_core_file (memaddr, myaddr, len)
     CORE_ADDR memaddr;
     char *myaddr;
     int len;
{
  register int i;
  register int val;
  int xferchan;
  char **xferfile;
  int fileptr;
  int returnval = 0;

  while (len > 0)
    {
      xferfile = 0;
      xferchan = 0;

      /* Determine which file the next bunch of addresses reside in,
         and where in the file.  Set the file's read/write pointer
         to point at the proper place for the desired address
         and set xferfile and xferchan for the correct file.

         If desired address is nonexistent, leave them zero.

         i is set to the number of bytes that can be handled
         along with the next address.

         We put the most likely tests first for efficiency.  */

      /* Note that if there is no core file
         data_start and data_end are equal.  */
      if (memaddr >= data_start && memaddr < data_end)
	{
	  i = min (len, data_end - memaddr);
	  fileptr = memaddr - data_start + data_offset;
	  xferfile = &corefile;
	  xferchan = corechan;
	}
      /* Note that if there is no core file
         stack_start and stack_end define the shared library data.  */
      else if (memaddr >= stack_start && memaddr < stack_end)
	{
	  if (corechan < 0)
	    {
	      struct shared_library *lib;
	      for (lib = shlib; lib; lib = lib->shares)
		if (memaddr >= lib->header.a_exec.a_sldatabase &&
		    memaddr < lib->header.a_exec.a_sldatabase +
		    lib->header.a_exec.a_data)
		  break;
	      if (lib)
		{
		  i = min (len, lib->header.a_exec.a_sldatabase +
			   lib->header.a_exec.a_data - memaddr);
		  fileptr = lib->data_offset + memaddr -
		    lib->header.a_exec.a_sldatabase;
		  xferfile = execfile;
		  xferchan = lib->chan;
		}
	    }
	  else
	    {
	      i = min (len, stack_end - memaddr);
	      fileptr = memaddr - stack_start + stack_offset;
	      xferfile = &corefile;
	      xferchan = corechan;
	    }
	}
      else if (corechan < 0
	       && memaddr >= exec_data_start && memaddr < exec_data_end)
	{
	  i = min (len, exec_data_end - memaddr);
	  fileptr = memaddr - exec_data_start + exec_data_offset;
	  xferfile = &execfile;
	  xferchan = execchan;
	}
      else if (memaddr >= text_start && memaddr < text_end)
	{
	  struct shared_library *lib;
	  for (lib = shlib; lib; lib = lib->shares)
	    if (memaddr >= lib->text_start &&
		memaddr < lib->text_start + lib->header.a_exec.a_text)
	      break;
	  if (lib)
	    {
	      i = min (len, lib->header.a_exec.a_text +
		       lib->text_start - memaddr);
	      fileptr = memaddr - lib->text_start + text_offset;
	      xferfile = &execfile;
	      xferchan = lib->chan;
	    }
	  else
	    {
	      i = min (len, text_end - memaddr);
	      fileptr = memaddr - unshared_text_start + text_offset;
	      xferfile = &execfile;
	      xferchan = execchan;
	    }
	}
      else if (memaddr < text_start)
	{
	  i = min (len, text_start - memaddr);
	}
      else if (memaddr >= text_end
	       && memaddr < (corechan >= 0 ? data_start : exec_data_start))
	{
	  i = min (len, data_start - memaddr);
	}
      else if (corechan >= 0
	       && memaddr >= data_end && memaddr < stack_start)
	{
	  i = min (len, stack_start - memaddr);
	}
      else if (corechan < 0 && memaddr >= exec_data_end)
	{
	  i = min (len, -memaddr);
	}
      else if (memaddr >= stack_end && stack_end != 0)
	{
	  i = min (len, -memaddr);
	}
      else
	{
	  /* Address did not classify into one of the known ranges.
	     This shouldn't happen; we catch the endpoints.  */
	  internal_error ("Bad case logic in xfer_core_file.");
	}

      /* Now we know which file to use.
         Set up its pointer and transfer the data.  */
      if (xferfile)
	{
	  if (*xferfile == 0)
	    if (xferfile == &execfile)
	      error ("No program file to examine.");
	    else
	      error ("No core dump file or running program to examine.");
	  val = lseek (xferchan, fileptr, 0);
	  if (val < 0)
	    perror_with_name (*xferfile);
	  val = myread (xferchan, myaddr, i);
	  if (val < 0)
	    perror_with_name (*xferfile);
	}
      /* If this address is for nonexistent memory,
         read zeros if reading, or do nothing if writing.
         Actually, we never right.  */
      else
	{
	  memset (myaddr, '\0', i);
	  returnval = EIO;
	}

      memaddr += i;
      myaddr += i;
      len -= i;
    }
  return returnval;
}
#endif
