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

   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 "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 (exception, RETURN_MASK_ALL)
    {
      return;
    }
  END_CATCH

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