/* Target-dependent code for GNU/Linux SPARC.

   Copyright (C) 2003-2018 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 "dwarf2-frame.h"
#include "frame.h"
#include "frame-unwind.h"
#include "gdbtypes.h"
#include "regset.h"
#include "gdbarch.h"
#include "gdbcore.h"
#include "osabi.h"
#include "regcache.h"
#include "solib-svr4.h"
#include "symtab.h"
#include "trad-frame.h"
#include "tramp-frame.h"
#include "xml-syscall.h"
#include "linux-tdep.h"

/* The syscall's XML filename for sparc 32-bit.  */
#define XML_SYSCALL_FILENAME_SPARC32 "syscalls/sparc-linux.xml"

#include "sparc-tdep.h"

/* Signal trampoline support.  */

static void sparc32_linux_sigframe_init (const struct tramp_frame *self,
					 struct frame_info *this_frame,
					 struct trad_frame_cache *this_cache,
					 CORE_ADDR func);

/* GNU/Linux has two flavors of signals.  Normal signal handlers, and
   "realtime" (RT) signals.  The RT signals can provide additional
   information to the signal handler if the SA_SIGINFO flag is set
   when establishing a signal handler using `sigaction'.  It is not
   unlikely that future versions of GNU/Linux will support SA_SIGINFO
   for normal signals too.  */

/* When the sparc Linux kernel calls a signal handler and the
   SA_RESTORER flag isn't set, the return address points to a bit of
   code on the stack.  This code checks whether the PC appears to be
   within this bit of code.

   The instruction sequence for normal signals is encoded below.
   Checking for the code sequence should be somewhat reliable, because
   the effect is to call the system call sigreturn.  This is unlikely
   to occur anywhere other than a signal trampoline.  */

static const struct tramp_frame sparc32_linux_sigframe =
{
  SIGTRAMP_FRAME,
  4,
  {
    { 0x821020d8, -1 },		/* mov __NR_sugreturn, %g1 */
    { 0x91d02010, -1 },		/* ta  0x10 */
    { TRAMP_SENTINEL_INSN, -1 }
  },
  sparc32_linux_sigframe_init
};

/* The instruction sequence for RT signals is slightly different.  The
   effect is to call the system call rt_sigreturn.  */

static const struct tramp_frame sparc32_linux_rt_sigframe =
{
  SIGTRAMP_FRAME,
  4,
  {
    { 0x82102065, -1 },		/* mov __NR_rt_sigreturn, %g1 */
    { 0x91d02010, -1 },		/* ta  0x10 */
    { TRAMP_SENTINEL_INSN, -1 }
  },
  sparc32_linux_sigframe_init
};

/* This enum represents the signals' numbers on the SPARC
   architecture.  It just contains the signal definitions which are
   different from the generic implementation.

   It is derived from the file <arch/sparc/include/uapi/asm/signal.h>,
   from the Linux kernel tree.  */

enum
  {
    SPARC_LINUX_SIGEMT = 7,
    SPARC_LINUX_SIGBUS = 10,
    SPARC_LINUX_SIGSYS = 12,
    SPARC_LINUX_SIGURG = 16,
    SPARC_LINUX_SIGSTOP = 17,
    SPARC_LINUX_SIGTSTP = 18,
    SPARC_LINUX_SIGCONT = 19,
    SPARC_LINUX_SIGCHLD = 20,
    SPARC_LINUX_SIGIO = 23,
    SPARC_LINUX_SIGPOLL = SPARC_LINUX_SIGIO,
    SPARC_LINUX_SIGLOST = 29,
    SPARC_LINUX_SIGPWR = SPARC_LINUX_SIGLOST,
    SPARC_LINUX_SIGUSR1 = 30,
    SPARC_LINUX_SIGUSR2 = 31,
  };

static void
sparc32_linux_sigframe_init (const struct tramp_frame *self,
			     struct frame_info *this_frame,
			     struct trad_frame_cache *this_cache,
			     CORE_ADDR func)
{
  CORE_ADDR base, addr, sp_addr;
  int regnum;

  base = get_frame_register_unsigned (this_frame, SPARC_O1_REGNUM);
  if (self == &sparc32_linux_rt_sigframe)
    base += 128;

  /* Offsets from <bits/sigcontext.h>.  */

  trad_frame_set_reg_addr (this_cache, SPARC32_PSR_REGNUM, base + 0);
  trad_frame_set_reg_addr (this_cache, SPARC32_PC_REGNUM, base + 4);
  trad_frame_set_reg_addr (this_cache, SPARC32_NPC_REGNUM, base + 8);
  trad_frame_set_reg_addr (this_cache, SPARC32_Y_REGNUM, base + 12);

  /* Since %g0 is always zero, keep the identity encoding.  */
  addr = base + 20;
  sp_addr = base + 16 + ((SPARC_SP_REGNUM - SPARC_G0_REGNUM) * 4);
  for (regnum = SPARC_G1_REGNUM; regnum <= SPARC_O7_REGNUM; regnum++)
    {
      trad_frame_set_reg_addr (this_cache, regnum, addr);
      addr += 4;
    }

  base = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
  addr = get_frame_memory_unsigned (this_frame, sp_addr, 4);

  for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
    {
      trad_frame_set_reg_addr (this_cache, regnum, addr);
      addr += 4;
    }
  trad_frame_set_id (this_cache, frame_id_build (base, func));
}

/* Return the address of a system call's alternative return
   address.  */

static CORE_ADDR
sparc32_linux_step_trap (struct frame_info *frame, unsigned long insn)
{
  if (insn == 0x91d02010)
    {
      ULONGEST sc_num = get_frame_register_unsigned (frame, SPARC_G1_REGNUM);

      /* __NR_rt_sigreturn is 101 and __NR_sigreturn is 216.  */
      if (sc_num == 101 || sc_num == 216)
	{
	  struct gdbarch *gdbarch = get_frame_arch (frame);
	  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

	  ULONGEST sp, pc_offset;

	  sp = get_frame_register_unsigned (frame, SPARC_SP_REGNUM);

	  /* The kernel puts the sigreturn registers on the stack,
	     and this is where the signal unwinding state is take from
	     when returning from a signal.

	     For __NR_sigreturn, this register area sits 96 bytes from
	     the base of the stack.  The saved PC sits 4 bytes into the
	     sigreturn register save area.

	     For __NR_rt_sigreturn a siginfo_t, which is 128 bytes, sits
	     right before the sigreturn register save area.  */

	  pc_offset = 96 + 4;
	  if (sc_num == 101)
	    pc_offset += 128;

	  return read_memory_unsigned_integer (sp + pc_offset, 4, byte_order);
	}
    }

  return 0;
}


const struct sparc_gregmap sparc32_linux_core_gregmap =
{
  32 * 4,			/* %psr */
  33 * 4,			/* %pc */
  34 * 4,			/* %npc */
  35 * 4,			/* %y */
  -1,				/* %wim */
  -1,				/* %tbr */
  1 * 4,			/* %g1 */
  16 * 4,			/* %l0 */
  4,				/* y size */
};


static void
sparc32_linux_supply_core_gregset (const struct regset *regset,
				   struct regcache *regcache,
				   int regnum, const void *gregs, size_t len)
{
  sparc32_supply_gregset (&sparc32_linux_core_gregmap,
			  regcache, regnum, gregs);
}

static void
sparc32_linux_collect_core_gregset (const struct regset *regset,
				    const struct regcache *regcache,
				    int regnum, void *gregs, size_t len)
{
  sparc32_collect_gregset (&sparc32_linux_core_gregmap,
			   regcache, regnum, gregs);
}

static void
sparc32_linux_supply_core_fpregset (const struct regset *regset,
				    struct regcache *regcache,
				    int regnum, const void *fpregs, size_t len)
{
  sparc32_supply_fpregset (&sparc32_bsd_fpregmap, regcache, regnum, fpregs);
}

static void
sparc32_linux_collect_core_fpregset (const struct regset *regset,
				     const struct regcache *regcache,
				     int regnum, void *fpregs, size_t len)
{
  sparc32_collect_fpregset (&sparc32_bsd_fpregmap, regcache, regnum, fpregs);
}

/* Set the program counter for process PTID to PC.  */

#define PSR_SYSCALL	0x00004000

static void
sparc_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
  ULONGEST psr;

  regcache_cooked_write_unsigned (regcache, tdep->pc_regnum, pc);
  regcache_cooked_write_unsigned (regcache, tdep->npc_regnum, pc + 4);

  /* Clear the "in syscall" bit to prevent the kernel from
     messing with the PCs we just installed, if we happen to be
     within an interrupted system call that the kernel wants to
     restart.

     Note that after we return from the dummy call, the PSR et al.
     registers will be automatically restored, and the kernel
     continues to restart the system call at this point.  */
  regcache_cooked_read_unsigned (regcache, SPARC32_PSR_REGNUM, &psr);
  psr &= ~PSR_SYSCALL;
  regcache_cooked_write_unsigned (regcache, SPARC32_PSR_REGNUM, psr);
}

static LONGEST
sparc32_linux_get_syscall_number (struct gdbarch *gdbarch,
				  ptid_t ptid)
{
  struct regcache *regcache = get_thread_regcache (ptid);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  /* The content of a register.  */
  gdb_byte buf[4];
  /* The result.  */
  LONGEST ret;

  /* Getting the system call number from the register.
     When dealing with the sparc architecture, this information
     is stored at the %g1 register.  */
  regcache_cooked_read (regcache, SPARC_G1_REGNUM, buf);

  ret = extract_signed_integer (buf, 4, byte_order);

  return ret;
}

/* Implementation of `gdbarch_gdb_signal_from_target', as defined in
   gdbarch.h.  */

static enum gdb_signal
sparc32_linux_gdb_signal_from_target (struct gdbarch *gdbarch,
				      int signal)
{
  switch (signal)
    {
    case SPARC_LINUX_SIGEMT:
      return GDB_SIGNAL_EMT;

    case SPARC_LINUX_SIGBUS:
      return GDB_SIGNAL_BUS;

    case SPARC_LINUX_SIGSYS:
      return GDB_SIGNAL_SYS;

    case SPARC_LINUX_SIGURG:
      return GDB_SIGNAL_URG;

    case SPARC_LINUX_SIGSTOP:
      return GDB_SIGNAL_STOP;

    case SPARC_LINUX_SIGTSTP:
      return GDB_SIGNAL_TSTP;

    case SPARC_LINUX_SIGCONT:
      return GDB_SIGNAL_CONT;

    case SPARC_LINUX_SIGCHLD:
      return GDB_SIGNAL_CHLD;

    /* No way to differentiate between SIGIO and SIGPOLL.
       Therefore, we just handle the first one.  */
    case SPARC_LINUX_SIGIO:
      return GDB_SIGNAL_IO;

    /* No way to differentiate between SIGLOST and SIGPWR.
       Therefore, we just handle the first one.  */
    case SPARC_LINUX_SIGLOST:
      return GDB_SIGNAL_LOST;

    case SPARC_LINUX_SIGUSR1:
      return GDB_SIGNAL_USR1;

    case SPARC_LINUX_SIGUSR2:
      return GDB_SIGNAL_USR2;
    }

  return linux_gdb_signal_from_target (gdbarch, signal);
}

/* Implementation of `gdbarch_gdb_signal_to_target', as defined in
   gdbarch.h.  */

static int
sparc32_linux_gdb_signal_to_target (struct gdbarch *gdbarch,
				    enum gdb_signal signal)
{
  switch (signal)
    {
    case GDB_SIGNAL_EMT:
      return SPARC_LINUX_SIGEMT;

    case GDB_SIGNAL_BUS:
      return SPARC_LINUX_SIGBUS;

    case GDB_SIGNAL_SYS:
      return SPARC_LINUX_SIGSYS;

    case GDB_SIGNAL_URG:
      return SPARC_LINUX_SIGURG;

    case GDB_SIGNAL_STOP:
      return SPARC_LINUX_SIGSTOP;

    case GDB_SIGNAL_TSTP:
      return SPARC_LINUX_SIGTSTP;

    case GDB_SIGNAL_CONT:
      return SPARC_LINUX_SIGCONT;

    case GDB_SIGNAL_CHLD:
      return SPARC_LINUX_SIGCHLD;

    case GDB_SIGNAL_IO:
      return SPARC_LINUX_SIGIO;

    case GDB_SIGNAL_POLL:
      return SPARC_LINUX_SIGPOLL;

    case GDB_SIGNAL_LOST:
      return SPARC_LINUX_SIGLOST;

    case GDB_SIGNAL_PWR:
      return SPARC_LINUX_SIGPWR;

    case GDB_SIGNAL_USR1:
      return SPARC_LINUX_SIGUSR1;

    case GDB_SIGNAL_USR2:
      return SPARC_LINUX_SIGUSR2;
    }

  return linux_gdb_signal_to_target (gdbarch, signal);
}



static const struct regset sparc32_linux_gregset =
  {
    NULL,
    sparc32_linux_supply_core_gregset,
    sparc32_linux_collect_core_gregset
  };

static const struct regset sparc32_linux_fpregset =
  {
    NULL,
    sparc32_linux_supply_core_fpregset,
    sparc32_linux_collect_core_fpregset
  };

static void
sparc32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  linux_init_abi (info, gdbarch);

  tdep->gregset = &sparc32_linux_gregset;
  tdep->sizeof_gregset = 152;

  tdep->fpregset = &sparc32_linux_fpregset;
  tdep->sizeof_fpregset = 396;

  tramp_frame_prepend_unwinder (gdbarch, &sparc32_linux_sigframe);
  tramp_frame_prepend_unwinder (gdbarch, &sparc32_linux_rt_sigframe);

  /* GNU/Linux has SVR4-style shared libraries...  */
  set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
  set_solib_svr4_fetch_link_map_offsets
    (gdbarch, svr4_ilp32_fetch_link_map_offsets);

  /* ...which means that we need some special handling when doing
     prologue analysis.  */
  tdep->plt_entry_size = 12;

  /* Enable TLS support.  */
  set_gdbarch_fetch_tls_load_module_address (gdbarch,
                                             svr4_fetch_objfile_link_map);

  /* Make sure we can single-step over signal return system calls.  */
  tdep->step_trap = sparc32_linux_step_trap;

  /* Hook in the DWARF CFI frame unwinder.  */
  dwarf2_append_unwinders (gdbarch);

  set_gdbarch_write_pc (gdbarch, sparc_linux_write_pc);

  /* Functions for 'catch syscall'.  */
  set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_SPARC32);
  set_gdbarch_get_syscall_number (gdbarch,
                                  sparc32_linux_get_syscall_number);

  set_gdbarch_gdb_signal_from_target (gdbarch,
				      sparc32_linux_gdb_signal_from_target);
  set_gdbarch_gdb_signal_to_target (gdbarch,
				    sparc32_linux_gdb_signal_to_target);
}

void
_initialize_sparc_linux_tdep (void)
{
  gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_LINUX,
			  sparc32_linux_init_abi);
}
