/* Target-dependent code for GNU/Linux running on the Fujitsu FR-V,
   for GDB.

   Copyright (C) 2004, 2006, 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 "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 (struct gdbarch *gdbarch, CORE_ADDR pc, char *name)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  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, byte_order);

  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, byte_order);
  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 *this_frame, int regno,
                               CORE_ADDR *sc_addr_cache_ptr)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  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 = get_frame_pc (this_frame);
      tramp_type = frv_linux_pc_in_sigtramp (gdbarch, pc, 0);

      get_frame_register (this_frame, sp_regnum, buf);
      sp = extract_unsigned_integer (buf, sizeof buf, byte_order);

      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, byte_order);
 	  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 *this_frame, void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct trad_frame_cache *cache;
  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 (this_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.  */
  get_frame_register (this_frame, sp_regnum, buf);
  addr = extract_unsigned_integer (buf, sizeof buf, byte_order);
  this_id = frame_id_build (addr, get_frame_pc (this_frame));
  trad_frame_set_id (cache, this_id);

  for (regnum = 0; regnum < frv_num_regs; regnum++)
    {
      LONGEST reg_addr = frv_linux_sigcontext_reg_addr (this_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 *this_frame, void **this_cache,
			     struct frame_id *this_id)
{
  struct trad_frame_cache *cache =
    frv_linux_sigtramp_frame_cache (this_frame, this_cache);
  trad_frame_get_id (cache, this_id);
}

static struct value *
frv_linux_sigtramp_frame_prev_register (struct frame_info *this_frame,
					void **this_cache, int regnum)
{
  /* Make sure we've initialized the cache.  */
  struct trad_frame_cache *cache =
    frv_linux_sigtramp_frame_cache (this_frame, this_cache);
  return trad_frame_get_register (cache, this_frame, regnum);
}

static int
frv_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
				  struct frame_info *this_frame,
				  void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  CORE_ADDR pc = get_frame_pc (this_frame);
  char *name;

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

  return 0;
}

static const struct frame_unwind frv_linux_sigtramp_frame_unwind =
{
  SIGTRAMP_FRAME,
  frv_linux_sigtramp_frame_this_id,
  frv_linux_sigtramp_frame_prev_register,
  NULL,
  frv_linux_sigtramp_frame_sniffer
};

/* 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 kernel 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_unwinder (gdbarch, &frv_linux_sigtramp_frame_unwind); 
  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);
}
