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

   Copyright (C) 2004-2025 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 "extract-store-integer.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 "linux-tdep.h"
#include "gdbarch.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,
			  const char *name)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  gdb_byte 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 (const frame_info_ptr &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;
      gdb_byte 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 (_("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 (const frame_info_ptr &this_frame,
				void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct trad_frame_cache *cache;
  CORE_ADDR addr;
  gdb_byte buf[4];
  int regnum;
  CORE_ADDR sc_addr_cache_val = 0;
  struct frame_id this_id;

  if (*this_cache)
    return (struct trad_frame_cache *) *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 (const frame_info_ptr &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 (const frame_info_ptr &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,
				  const frame_info_ptr &this_frame,
				  void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  CORE_ADDR pc = get_frame_pc (this_frame);
  const 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_legacy frv_linux_sigtramp_frame_unwind (
  "frv linux sigtramp",
  SIGTRAMP_FRAME,
  FRAME_UNWIND_ARCH,
  default_frame_unwind_stop_reason,
  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;

/* Register maps.  */

static const struct regcache_map_entry frv_linux_gregmap[] =
  {
    { 1, psr_regnum, 4 },
    { 1, REGCACHE_MAP_SKIP, 4 }, /* isr */
    { 1, ccr_regnum, 4 },
    { 1, cccr_regnum, 4 },
    { 1, lr_regnum, 4 },
    { 1, lcr_regnum, 4 },
    { 1, pc_regnum, 4 },
    { 1, REGCACHE_MAP_SKIP, 4 }, /* __status */
    { 1, REGCACHE_MAP_SKIP, 4 }, /* syscallno */
    { 1, REGCACHE_MAP_SKIP, 4 }, /* orig_gr8 */
    { 1, gner0_regnum, 4 },
    { 1, gner1_regnum, 4 },
    { 1, REGCACHE_MAP_SKIP, 8 }, /* iacc0 */
    { 1, tbr_regnum, 4 },
    { 31, first_gpr_regnum + 1, 4 }, /* gr1 ... gr31 */

    /* 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.  */

    { 1, fdpic_loadmap_exec_regnum, 4 },
    { 1, fdpic_loadmap_interp_regnum, 4 },
    { 0 }
  };

static const struct regcache_map_entry frv_linux_fpregmap[] =
  {
    { 64, first_fpr_regnum, 4 }, /* fr0 ... fr63 */
    { 1, fner0_regnum, 4 },
    { 1, fner1_regnum, 4 },
    { 1, msr0_regnum, 4 },
    { 1, msr1_regnum, 4 },
    { 8, acc0_regnum, 4 },	/* acc0 ... acc7 */
    { 1, accg0123_regnum, 4 },
    { 1, accg4567_regnum, 4 },
    { 1, fsr0_regnum, 4 },
    { 0 }
  };

/* 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;

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

  /* Fill gr32, ..., gr63 with zeros. */
  for (regi = first_gpr_regnum + 32; regi <= last_gpr_regnum; regi++)
    regcache->raw_supply_zeroed (regi);

  regcache_supply_regset (regset, regcache, regnum, gregs, len);
}

/* FRV Linux kernel register sets.  */

static const struct regset frv_linux_gregset =
{
  frv_linux_gregmap,
  frv_linux_supply_gregset, regcache_collect_regset
};

static const struct regset frv_linux_fpregset =
{
  frv_linux_fpregmap,
  regcache_supply_regset, regcache_collect_regset
};

static void
frv_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
					iterate_over_regset_sections_cb *cb,
					void *cb_data,
					const struct regcache *regcache)
{
  cb (".reg", sizeof (frv_elf_gregset_t), sizeof (frv_elf_gregset_t),
      &frv_linux_gregset, NULL, cb_data);
  cb (".reg2", sizeof (frv_elf_fpregset_t), sizeof (frv_elf_fpregset_t),
      &frv_linux_fpregset, NULL, cb_data);
}


static void
frv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  linux_init_abi (info, gdbarch, 0);

  /* Set the sigtramp frame sniffer.  */
  frame_unwind_append_unwinder (gdbarch, &frv_linux_sigtramp_frame_unwind);

  set_gdbarch_iterate_over_regset_sections
    (gdbarch, frv_linux_iterate_over_regset_sections);
}

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;
}

INIT_GDB_FILE (frv_linux_tdep)
{
  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);
}
