/* Target-dependent code for GNU/Linux running on the Fujitsu FR-V,
   for GDB.
   Copyright (C) 2004 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., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.  */

#include "defs.h"
#include "gdbcore.h"
#include "target.h"
#include "frame.h"
#include "osabi.h"
#include "regcache.h"
#include "elf-bfd.h"
#include "elf/frv.h"
#include "frv-tdep.h"
#include "trad-frame.h"
#include "frame-unwind.h"
#include "regset.h"
#include "gdb_string.h"

/* Define the size (in bytes) of an FR-V instruction.  */
static const int frv_instr_size = 4;

enum {
  NORMAL_SIGTRAMP = 1,
  RT_SIGTRAMP = 2
};

static int
frv_linux_pc_in_sigtramp (CORE_ADDR pc, char *name)
{
  char buf[frv_instr_size];
  LONGEST instr;
  int retval = 0;

  if (target_read_memory (pc, buf, sizeof buf) != 0)
    return 0;

  instr = extract_unsigned_integer (buf, sizeof buf);

  if (instr == 0x8efc0077)	/* setlos #__NR_sigreturn, gr7 */
    retval = NORMAL_SIGTRAMP;
  else if (instr -= 0x8efc00ad)	/* setlos #__NR_rt_sigreturn, gr7 */
    retval = RT_SIGTRAMP;
  else
    return 0;

  if (target_read_memory (pc + frv_instr_size, buf, sizeof buf) != 0)
    return 0;
  instr = extract_unsigned_integer (buf, sizeof buf);
  if (instr != 0xc0700000)	/* tira	gr0, 0 */
    return 0;

  /* If we get this far, we'll return a non-zero value, either
     NORMAL_SIGTRAMP (1) or RT_SIGTRAMP (2).  */
  return retval;
}

/* Given NEXT_FRAME, the "callee" frame of the sigtramp frame that we
   wish to decode, and REGNO, one of the frv register numbers defined
   in frv-tdep.h, return the address of the saved register (corresponding
   to REGNO) in the sigtramp frame.  Return -1 if the register is not
   found in the sigtramp frame.  The magic numbers in the code below
   were computed by examining the following kernel structs:

   From arch/frv/kernel/signal.c:

      struct sigframe
      {
	      void (*pretcode)(void);
	      int sig;
	      struct sigcontext sc;
	      unsigned long extramask[_NSIG_WORDS-1];
	      uint32_t retcode[2];
      };

      struct rt_sigframe
      {
	      void (*pretcode)(void);
	      int sig;
	      struct siginfo *pinfo;
	      void *puc;
	      struct siginfo info;
	      struct ucontext uc;
	      uint32_t retcode[2];
      };

   From include/asm-frv/ucontext.h:

      struct ucontext {
	      unsigned long		uc_flags;
	      struct ucontext		*uc_link;
	      stack_t			uc_stack;
	      struct sigcontext	uc_mcontext;
	      sigset_t		uc_sigmask;
      };

   From include/asm-frv/signal.h:

      typedef struct sigaltstack {
	      void *ss_sp;
	      int ss_flags;
	      size_t ss_size;
      } stack_t;

   From include/asm-frv/sigcontext.h:

      struct sigcontext {
	      struct user_context	sc_context;
	      unsigned long		sc_oldmask;
      } __attribute__((aligned(8)));

   From include/asm-frv/registers.h:
      struct user_int_regs
      {
	      unsigned long		psr;
	      unsigned long		isr;
	      unsigned long		ccr;
	      unsigned long		cccr;
	      unsigned long		lr;
	      unsigned long		lcr;
	      unsigned long		pc;
	      unsigned long		__status;
	      unsigned long		syscallno;
	      unsigned long		orig_gr8;
	      unsigned long		gner[2];
	      unsigned long long	iacc[1];

	      union {
		      unsigned long	tbr;
		      unsigned long	gr[64];
	      };
      };

      struct user_fpmedia_regs
      {
	      unsigned long	fr[64];
	      unsigned long	fner[2];
	      unsigned long	msr[2];
	      unsigned long	acc[8];
	      unsigned char	accg[8];
	      unsigned long	fsr[1];
      };

      struct user_context
      {
	      struct user_int_regs		i;
	      struct user_fpmedia_regs	f;

	      void *extension;
      } __attribute__((aligned(8)));  */

static LONGEST
frv_linux_sigcontext_reg_addr (struct frame_info *next_frame, int regno,
                               CORE_ADDR *sc_addr_cache_ptr)
{
  CORE_ADDR sc_addr;

  if (sc_addr_cache_ptr && *sc_addr_cache_ptr)
    {
      sc_addr = *sc_addr_cache_ptr;
    }
  else
    {
      CORE_ADDR pc, sp;
      char buf[4];
      int tramp_type;

      pc = frame_pc_unwind (next_frame);
      tramp_type = frv_linux_pc_in_sigtramp (pc, 0);

      frame_unwind_register (next_frame, sp_regnum, buf);
      sp = extract_unsigned_integer (buf, sizeof buf);

      if (tramp_type == NORMAL_SIGTRAMP)
	{
	  /* For a normal sigtramp frame, the sigcontext struct starts
	     at SP + 8.  */
	  sc_addr = sp + 8;
	}
      else if (tramp_type == RT_SIGTRAMP)
	{
	  /* For a realtime sigtramp frame, SP + 12 contains a pointer
 	     to a ucontext struct.  The ucontext struct contains a
 	     sigcontext struct starting 24 bytes in.  (The offset of
 	     uc_mcontext within struct ucontext is derived as follows: 
 	     stack_t is a 12-byte struct and struct sigcontext is
 	     8-byte aligned.  This gives an offset of 8 + 12 + 4 (for
 	     padding) = 24.) */
	  if (target_read_memory (sp + 12, buf, sizeof buf) != 0)
	    {
	      warning (_("Can't read realtime sigtramp frame."));
	      return 0;
	    }
	  sc_addr = extract_unsigned_integer (buf, sizeof buf);
 	  sc_addr += 24;
	}
      else
	internal_error (__FILE__, __LINE__, _("not a signal trampoline"));

      if (sc_addr_cache_ptr)
	*sc_addr_cache_ptr = sc_addr;
    }

  switch (regno)
    {
    case psr_regnum :
      return sc_addr + 0;
    /* sc_addr + 4 has "isr", the Integer Status Register.  */
    case ccr_regnum :
      return sc_addr + 8;
    case cccr_regnum :
      return sc_addr + 12;
    case lr_regnum :
      return sc_addr + 16;
    case lcr_regnum :
      return sc_addr + 20;
    case pc_regnum :
      return sc_addr + 24;
    /* sc_addr + 28 is __status, the exception status.
       sc_addr + 32 is syscallno, the syscall number or -1.
       sc_addr + 36 is orig_gr8, the original syscall arg #1.
       sc_addr + 40 is gner[0].
       sc_addr + 44 is gner[1]. */
    case iacc0h_regnum :
      return sc_addr + 48;
    case iacc0l_regnum :
      return sc_addr + 52;
    default : 
      if (first_gpr_regnum <= regno && regno <= last_gpr_regnum)
	return sc_addr + 56 + 4 * (regno - first_gpr_regnum);
      else if (first_fpr_regnum <= regno && regno <= last_fpr_regnum)
	return sc_addr + 312 + 4 * (regno - first_fpr_regnum);
      else
	return -1;  /* not saved. */
    }
}

/* Signal trampolines.  */

static struct trad_frame_cache *
frv_linux_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache)
{
  struct trad_frame_cache *cache;
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
  CORE_ADDR addr;
  char buf[4];
  int regnum;
  CORE_ADDR sc_addr_cache_val = 0;
  struct frame_id this_id;

  if (*this_cache)
    return *this_cache;

  cache = trad_frame_cache_zalloc (next_frame);

  /* FIXME: cagney/2004-05-01: This is is long standing broken code.
     The frame ID's code address should be the start-address of the
     signal trampoline and not the current PC within that
     trampoline.  */
  frame_unwind_register (next_frame, sp_regnum, buf);
  this_id = frame_id_build (extract_unsigned_integer (buf, sizeof buf),
			    frame_pc_unwind (next_frame));
  trad_frame_set_id (cache, this_id);

  for (regnum = 0; regnum < frv_num_regs; regnum++)
    {
      LONGEST reg_addr = frv_linux_sigcontext_reg_addr (next_frame, regnum,
							&sc_addr_cache_val);
      if (reg_addr != -1)
	trad_frame_set_reg_addr (cache, regnum, reg_addr);
    }

  *this_cache = cache;
  return cache;
}

static void
frv_linux_sigtramp_frame_this_id (struct frame_info *next_frame, void **this_cache,
			     struct frame_id *this_id)
{
  struct trad_frame_cache *cache =
    frv_linux_sigtramp_frame_cache (next_frame, this_cache);
  trad_frame_get_id (cache, this_id);
}

static void
frv_linux_sigtramp_frame_prev_register (struct frame_info *next_frame,
				   void **this_cache,
				   int regnum, int *optimizedp,
				   enum lval_type *lvalp, CORE_ADDR *addrp,
				   int *realnump, gdb_byte *valuep)
{
  /* Make sure we've initialized the cache.  */
  struct trad_frame_cache *cache =
    frv_linux_sigtramp_frame_cache (next_frame, this_cache);
  trad_frame_get_register (cache, next_frame, regnum, optimizedp, lvalp,
			   addrp, realnump, valuep);
}

static const struct frame_unwind frv_linux_sigtramp_frame_unwind =
{
  SIGTRAMP_FRAME,
  frv_linux_sigtramp_frame_this_id,
  frv_linux_sigtramp_frame_prev_register
};

static const struct frame_unwind *
frv_linux_sigtramp_frame_sniffer (struct frame_info *next_frame)
{
  CORE_ADDR pc = frame_pc_unwind (next_frame);
  char *name;

  find_pc_partial_function (pc, &name, NULL, NULL);
  if (frv_linux_pc_in_sigtramp (pc, name))
    return &frv_linux_sigtramp_frame_unwind;

  return NULL;
}


/* The FRV kernel defines ELF_NGREG as 46.  We add 2 in order to include
   the loadmap addresses in the register set.  (See below for more info.)  */
#define FRV_ELF_NGREG (46 + 2)
typedef unsigned char frv_elf_greg_t[4];
typedef struct { frv_elf_greg_t reg[FRV_ELF_NGREG]; } frv_elf_gregset_t;

typedef unsigned char frv_elf_fpreg_t[4];
typedef struct
{
  frv_elf_fpreg_t fr[64];
  frv_elf_fpreg_t fner[2];
  frv_elf_fpreg_t msr[2];
  frv_elf_fpreg_t acc[8];
  unsigned char accg[8];
  frv_elf_fpreg_t fsr[1];
} frv_elf_fpregset_t;

/* Constants for accessing elements of frv_elf_gregset_t.  */

#define FRV_PT_PSR 0
#define	FRV_PT_ISR 1
#define FRV_PT_CCR 2
#define FRV_PT_CCCR 3
#define FRV_PT_LR 4
#define FRV_PT_LCR 5
#define FRV_PT_PC 6
#define FRV_PT_GNER0 10
#define FRV_PT_GNER1 11
#define FRV_PT_IACC0H 12
#define FRV_PT_IACC0L 13

/* Note: Only 32 of the GRs will be found in the corefile.  */
#define FRV_PT_GR(j)	( 14 + (j))	/* GRj for 0<=j<=63. */

#define FRV_PT_TBR FRV_PT_GR(0)		/* gr0 is always 0, so TBR is stuffed
					   there.  */

/* Technically, the loadmap addresses are not part of `pr_reg' as
   found in the elf_prstatus struct.  The fields which communicate the
   loadmap address appear (by design) immediately after `pr_reg'
   though, and the BFD function elf32_frv_grok_prstatus() has been
   implemented to include these fields in the register section that it
   extracts from the core file.  So, for our purposes, they may be
   viewed as registers.  */

#define FRV_PT_EXEC_FDPIC_LOADMAP 46
#define FRV_PT_INTERP_FDPIC_LOADMAP 47


/* Unpack an frv_elf_gregset_t into GDB's register cache.  */

static void 
frv_linux_supply_gregset (const struct regset *regset,
                          struct regcache *regcache,
			  int regnum, const void *gregs, size_t len)
{
  int regi;
  char zerobuf[MAX_REGISTER_SIZE];
  const frv_elf_gregset_t *gregsetp = gregs;

  memset (zerobuf, 0, MAX_REGISTER_SIZE);

  /* gr0 always contains 0.  Also, the kernel passes the TBR value in
     this slot.  */
  regcache_raw_supply (regcache, first_gpr_regnum, zerobuf);

  for (regi = first_gpr_regnum + 1; regi <= last_gpr_regnum; regi++)
    {
      if (regi >= first_gpr_regnum + 32)
	regcache_raw_supply (regcache, regi, zerobuf);
      else
	regcache_raw_supply (regcache, regi,
			     gregsetp->reg[FRV_PT_GR (regi - first_gpr_regnum)]);
    }

  regcache_raw_supply (regcache, pc_regnum, gregsetp->reg[FRV_PT_PC]);
  regcache_raw_supply (regcache, psr_regnum, gregsetp->reg[FRV_PT_PSR]);
  regcache_raw_supply (regcache, ccr_regnum, gregsetp->reg[FRV_PT_CCR]);
  regcache_raw_supply (regcache, cccr_regnum, gregsetp->reg[FRV_PT_CCCR]);
  regcache_raw_supply (regcache, lr_regnum, gregsetp->reg[FRV_PT_LR]);
  regcache_raw_supply (regcache, lcr_regnum, gregsetp->reg[FRV_PT_LCR]);
  regcache_raw_supply (regcache, gner0_regnum, gregsetp->reg[FRV_PT_GNER0]);
  regcache_raw_supply (regcache, gner1_regnum, gregsetp->reg[FRV_PT_GNER1]);
  regcache_raw_supply (regcache, tbr_regnum, gregsetp->reg[FRV_PT_TBR]);
  regcache_raw_supply (regcache, fdpic_loadmap_exec_regnum,
                       gregsetp->reg[FRV_PT_EXEC_FDPIC_LOADMAP]);
  regcache_raw_supply (regcache, fdpic_loadmap_interp_regnum,
                       gregsetp->reg[FRV_PT_INTERP_FDPIC_LOADMAP]);
}

/* Unpack an frv_elf_fpregset_t into GDB's register cache.  */

static void
frv_linux_supply_fpregset (const struct regset *regset,
                           struct regcache *regcache,
			   int regnum, const void *gregs, size_t len)
{
  int regi;
  const frv_elf_fpregset_t *fpregsetp = gregs;

  for (regi = first_fpr_regnum; regi <= last_fpr_regnum; regi++)
    regcache_raw_supply (regcache, regi, fpregsetp->fr[regi - first_fpr_regnum]);

  regcache_raw_supply (regcache, fner0_regnum, fpregsetp->fner[0]);
  regcache_raw_supply (regcache, fner1_regnum, fpregsetp->fner[1]);

  regcache_raw_supply (regcache, msr0_regnum, fpregsetp->msr[0]);
  regcache_raw_supply (regcache, msr1_regnum, fpregsetp->msr[1]);

  for (regi = acc0_regnum; regi <= acc7_regnum; regi++)
    regcache_raw_supply (regcache, regi, fpregsetp->acc[regi - acc0_regnum]);

  regcache_raw_supply (regcache, accg0123_regnum, fpregsetp->accg);
  regcache_raw_supply (regcache, accg4567_regnum, fpregsetp->accg + 4);

  regcache_raw_supply (regcache, fsr0_regnum, fpregsetp->fsr[0]);
}

/* FRV Linux register sets.  */

static struct regset frv_linux_gregset =
{
  NULL,
  frv_linux_supply_gregset
};

static struct regset frv_linux_fpregset =
{
  NULL,
  frv_linux_supply_fpregset
};

static const struct regset *
frv_linux_regset_from_core_section (struct gdbarch *gdbarch,
				    const char *sect_name, size_t sect_size)
{
  if (strcmp (sect_name, ".reg") == 0 
      && sect_size >= sizeof (frv_elf_gregset_t))
    return &frv_linux_gregset;

  if (strcmp (sect_name, ".reg2") == 0 
      && sect_size >= sizeof (frv_elf_fpregset_t))
    return &frv_linux_fpregset;

  return NULL;
}


static void
frv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  /* Set the sigtramp frame sniffer.  */
  frame_unwind_append_sniffer (gdbarch, frv_linux_sigtramp_frame_sniffer); 
  set_gdbarch_regset_from_core_section (gdbarch,
                                        frv_linux_regset_from_core_section);
}

static enum gdb_osabi
frv_linux_elf_osabi_sniffer (bfd *abfd)
{
  int elf_flags;

  elf_flags = elf_elfheader (abfd)->e_flags;

  /* Assume GNU/Linux if using the FDPIC ABI.  If/when another OS shows
     up that uses this ABI, we'll need to start using .note sections
     or some such.  */
  if (elf_flags & EF_FRV_FDPIC)
    return GDB_OSABI_LINUX;
  else
    return GDB_OSABI_UNKNOWN;
}

/* Provide a prototype to silence -Wmissing-prototypes.  */
void _initialize_frv_linux_tdep (void);

void
_initialize_frv_linux_tdep (void)
{
  gdbarch_register_osabi (bfd_arch_frv, 0, GDB_OSABI_LINUX, frv_linux_init_abi);
  gdbarch_register_osabi_sniffer (bfd_arch_frv,
				  bfd_target_elf_flavour,
				  frv_linux_elf_osabi_sniffer);
}
