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

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

/* ADI specific si_code */
#ifndef SEGV_ACCADI
#define SEGV_ACCADI	3
#endif
#ifndef SEGV_ADIDERR
#define SEGV_ADIDERR	4
#endif
#ifndef SEGV_ADIPERR
#define SEGV_ADIPERR	5
#endif

/* The syscall's XML filename for sparc 64-bit.  */
#define XML_SYSCALL_FILENAME_SPARC64 "syscalls/sparc64-linux.xml"

#include "sparc64-tdep.h"

/* Signal trampoline support.  */

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

/* See sparc-linux-tdep.c for details.  Note that 64-bit binaries only
   use RT signals.  */

static const struct tramp_frame sparc64_linux_rt_sigframe =
{
  SIGTRAMP_FRAME,
  4,
  {
    { 0x82102065, ULONGEST_MAX },		/* mov __NR_rt_sigreturn, %g1 */
    { 0x91d0206d, ULONGEST_MAX },		/* ta  0x6d */
    { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
  },
  sparc64_linux_sigframe_init
};

static void
sparc64_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);
  base += 128;

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

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

  trad_frame_set_reg_addr (this_cache, SPARC64_STATE_REGNUM, addr + 0);
  trad_frame_set_reg_addr (this_cache, SPARC64_PC_REGNUM, addr + 8);
  trad_frame_set_reg_addr (this_cache, SPARC64_NPC_REGNUM, addr + 16);
  trad_frame_set_reg_addr (this_cache, SPARC64_Y_REGNUM, addr + 24);
  trad_frame_set_reg_addr (this_cache, SPARC64_FPRS_REGNUM, addr + 28);

  base = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
  if (base & 1)
    base += BIAS;

  addr = get_frame_memory_unsigned (this_frame, sp_addr, 8);
  if (addr & 1)
    addr += BIAS;

  for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
    {
      trad_frame_set_reg_addr (this_cache, regnum, addr);
      addr += 8;
    }
  trad_frame_set_id (this_cache, frame_id_build (base, func));
}

/* sparc64 GNU/Linux implementation of the handle_segmentation_fault
   gdbarch hook.
   Displays information related to ADI memory corruptions.  */

void
sparc64_linux_handle_segmentation_fault (struct gdbarch *gdbarch,
				      struct ui_out *uiout)
{
  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word != 64)
    return;

  CORE_ADDR addr = 0;
  long si_code = 0;

  try
    {
      /* Evaluate si_code to see if the segfault is ADI related.  */
      si_code = parse_and_eval_long ("$_siginfo.si_code\n");

      if (si_code >= SEGV_ACCADI && si_code <= SEGV_ADIPERR)
        addr = parse_and_eval_long ("$_siginfo._sifields._sigfault.si_addr");
    }
  catch (const gdb_exception &exception)
    {
      return;
    }

  /* Print out ADI event based on sig_code value */
  switch (si_code)
    {
    case SEGV_ACCADI:	/* adi not enabled */
      uiout->text ("\n");
      uiout->field_string ("sigcode-meaning", _("ADI disabled"));
      uiout->text (_(" while accessing address "));
      uiout->field_fmt ("bound-access", "%s", paddress (gdbarch, addr));
      break;
    case SEGV_ADIDERR:	/* disrupting mismatch */
      uiout->text ("\n");
      uiout->field_string ("sigcode-meaning", _("ADI deferred mismatch"));
      uiout->text (_(" while accessing address "));
      uiout->field_fmt ("bound-access", "%s", paddress (gdbarch, addr));
      break;
    case SEGV_ADIPERR:	/* precise mismatch */
      uiout->text ("\n");
      uiout->field_string ("sigcode-meaning", _("ADI precise mismatch"));
      uiout->text (_(" while accessing address "));
      uiout->field_fmt ("bound-access", "%s", paddress (gdbarch, addr));
      break;
    default:
      break;
    }

}


/* Return the address of a system call's alternative return
   address.  */

static CORE_ADDR
sparc64_linux_step_trap (struct frame_info *frame, unsigned long insn)
{
  /* __NR_rt_sigreturn is 101  */
  if ((insn == 0x91d0206d)
      && (get_frame_register_unsigned (frame, SPARC_G1_REGNUM) == 101))
    {
      struct gdbarch *gdbarch = get_frame_arch (frame);
      enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

      ULONGEST sp = get_frame_register_unsigned (frame, SPARC_SP_REGNUM);
      if (sp & 1)
	sp += BIAS;

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

	 A siginfo_t sits 192 bytes from the base of the stack.  This
	 siginfo_t is 128 bytes, and is followed by the sigreturn
	 register save area.  The saved PC sits at a 136 byte offset
	 into there.  */

      return read_memory_unsigned_integer (sp + 192 + 128 + 136,
					   8, byte_order);
    }

  return 0;
}


const struct sparc_gregmap sparc64_linux_core_gregmap =
{
  32 * 8,			/* %tstate */
  33 * 8,			/* %tpc */
  34 * 8,			/* %tnpc */
  35 * 8,			/* %y */
  -1,				/* %wim */
  -1,				/* %tbr */
  1 * 8,			/* %g1 */
  16 * 8,			/* %l0 */
  8,				/* y size */
};


static void
sparc64_linux_supply_core_gregset (const struct regset *regset,
				   struct regcache *regcache,
				   int regnum, const void *gregs, size_t len)
{
  sparc64_supply_gregset (&sparc64_linux_core_gregmap,
			  regcache, regnum, gregs);
}

static void
sparc64_linux_collect_core_gregset (const struct regset *regset,
				    const struct regcache *regcache,
				    int regnum, void *gregs, size_t len)
{
  sparc64_collect_gregset (&sparc64_linux_core_gregmap,
			   regcache, regnum, gregs);
}

static void
sparc64_linux_supply_core_fpregset (const struct regset *regset,
				    struct regcache *regcache,
				    int regnum, const void *fpregs, size_t len)
{
  sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
}

static void
sparc64_linux_collect_core_fpregset (const struct regset *regset,
				     const struct regcache *regcache,
				     int regnum, void *fpregs, size_t len)
{
  sparc64_collect_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
}

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

#define TSTATE_SYSCALL	0x0000000000000020ULL

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

  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 TSTATE et al.
     registers will be automatically restored, and the kernel
     continues to restart the system call at this point.  */
  regcache_cooked_read_unsigned (regcache, SPARC64_STATE_REGNUM, &state);
  state &= ~TSTATE_SYSCALL;
  regcache_cooked_write_unsigned (regcache, SPARC64_STATE_REGNUM, state);
}

static LONGEST
sparc64_linux_get_syscall_number (struct gdbarch *gdbarch,
				  thread_info *thread)
{
  struct regcache *regcache = get_thread_regcache (thread);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  /* The content of a register.  */
  gdb_byte buf[8];
  /* 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 (SPARC_G1_REGNUM, buf);

  ret = extract_signed_integer (buf, 8, byte_order);

  return ret;
}


/* Implement the "get_longjmp_target" gdbarch method.  */

static int
sparc64_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  CORE_ADDR jb_addr;
  gdb_byte buf[8];

  jb_addr = get_frame_register_unsigned (frame, SPARC_O0_REGNUM);

  /* setjmp and longjmp in SPARC64 are implemented in glibc using the
     setcontext and getcontext system calls respectively.  These
     system calls operate on ucontext_t structures, which happen to
     partially have the same structure than jmp_buf.  However the
     ucontext returned by getcontext, and thus the jmp_buf structure
     returned by setjmp, contains the context of the trap instruction
     in the glibc __[sig]setjmp wrapper, not the context of the user
     code calling setjmp.

     %o7 in the jmp_buf structure is stored at offset 18*8 in the
     mc_gregs array, which is itself located at offset 32 into
     jmp_buf.  See bits/setjmp.h.  This register contains the address
     of the 'call setjmp' instruction in user code.

     In order to determine the longjmp target address in the
     initiating frame we need to examine the call instruction itself,
     in particular whether the annul bit is set.  If it is not set
     then we need to jump over the instruction at the delay slot.  */

  if (target_read_memory (jb_addr + 32 + (18 * 8), buf, 8))
    return 0;

  *pc = extract_unsigned_integer (buf, 8, gdbarch_byte_order (gdbarch));

  if (!sparc_is_annulled_branch_insn (*pc))
      *pc += 4; /* delay slot insn  */
  *pc += 4; /* call insn  */

  return 1;
}



static const struct regset sparc64_linux_gregset =
  {
    NULL,
    sparc64_linux_supply_core_gregset,
    sparc64_linux_collect_core_gregset
  };

static const struct regset sparc64_linux_fpregset =
  {
    NULL,
    sparc64_linux_supply_core_fpregset,
    sparc64_linux_collect_core_fpregset
  };

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

  linux_init_abi (info, gdbarch);

  tdep->gregset = &sparc64_linux_gregset;
  tdep->sizeof_gregset = 288;

  tdep->fpregset = &sparc64_linux_fpregset;
  tdep->sizeof_fpregset = 280;

  tramp_frame_prepend_unwinder (gdbarch, &sparc64_linux_rt_sigframe);

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

  sparc64_init_abi (info, gdbarch);

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

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

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

  /* Make sure we can single-step over longjmp calls.  */
  set_gdbarch_get_longjmp_target (gdbarch, sparc64_linux_get_longjmp_target);

  set_gdbarch_write_pc (gdbarch, sparc64_linux_write_pc);

  /* Functions for 'catch syscall'.  */
  set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_SPARC64);
  set_gdbarch_get_syscall_number (gdbarch,
                                  sparc64_linux_get_syscall_number);
  set_gdbarch_handle_segmentation_fault (gdbarch,
					 sparc64_linux_handle_segmentation_fault);
}

void
_initialize_sparc64_linux_tdep (void)
{
  gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
			  GDB_OSABI_LINUX, sparc64_linux_init_abi);
}
