/* Target-dependent code for GNU/Linux on RISC-V processors.
   Copyright (C) 2018-2021 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 "riscv-tdep.h"
#include "osabi.h"
#include "glibc-tdep.h"
#include "linux-tdep.h"
#include "solib-svr4.h"
#include "regset.h"
#include "tramp-frame.h"
#include "trad-frame.h"
#include "gdbarch.h"

/* Define the general register mapping.  The kernel puts the PC at offset 0,
   gdb puts it at offset 32.  Register x0 is always 0 and can be ignored.
   Registers x1 to x31 are in the same place.  */

static const struct regcache_map_entry riscv_linux_gregmap[] =
{
  { 1,  RISCV_PC_REGNUM, 0 },
  { 31, RISCV_RA_REGNUM, 0 }, /* x1 to x31 */
  { 0 }
};

/* Define the FP register mapping.  The kernel puts the 32 FP regs first, and
   then FCSR.  */

static const struct regcache_map_entry riscv_linux_fregmap[] =
{
  { 32, RISCV_FIRST_FP_REGNUM, 0 },
  { 1, RISCV_CSR_FCSR_REGNUM, 0 },
  { 0 }
};

/* Define the general register regset.  */

static const struct regset riscv_linux_gregset =
{
  riscv_linux_gregmap, riscv_supply_regset, regcache_collect_regset
};

/* Define the FP register regset.  */

static const struct regset riscv_linux_fregset =
{
  riscv_linux_fregmap, riscv_supply_regset, regcache_collect_regset
};

/* Define hook for core file support.  */

static void
riscv_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
					  iterate_over_regset_sections_cb *cb,
					  void *cb_data,
					  const struct regcache *regcache)
{
  cb (".reg", (32 * riscv_isa_xlen (gdbarch)), (32 * riscv_isa_xlen (gdbarch)),
      &riscv_linux_gregset, NULL, cb_data);
  /* The kernel is adding 8 bytes for FCSR.  */
  cb (".reg2", (32 * riscv_isa_flen (gdbarch)) + 8,
      (32 * riscv_isa_flen (gdbarch)) + 8,
      &riscv_linux_fregset, NULL, cb_data);
}

/* Signal trampoline support.  */

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

#define RISCV_INST_LI_A7_SIGRETURN	0x08b00893
#define RISCV_INST_ECALL		0x00000073

static const struct tramp_frame riscv_linux_sigframe = {
  SIGTRAMP_FRAME,
  4,
  {
    { RISCV_INST_LI_A7_SIGRETURN, ULONGEST_MAX },
    { RISCV_INST_ECALL, ULONGEST_MAX },
    { TRAMP_SENTINEL_INSN }
  },
  riscv_linux_sigframe_init,
  NULL
};

/* Runtime signal frames look like this:
   struct rt_sigframe {
     struct siginfo info;
     struct ucontext uc;
   };

   struct ucontext {
     unsigned long __uc_flags;
     struct ucontext *uclink;
     stack_t uc_stack;
     sigset_t uc_sigmask;
     char __glibc_reserved[1024 / 8 - sizeof (sigset_t)];
     mcontext_t uc_mcontext;
   }; */

#define SIGFRAME_SIGINFO_SIZE		128
#define UCONTEXT_MCONTEXT_OFFSET	176

static void
riscv_linux_sigframe_init (const struct tramp_frame *self,
			   struct frame_info *this_frame,
			   struct trad_frame_cache *this_cache,
			   CORE_ADDR func)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  int xlen = riscv_isa_xlen (gdbarch);
  int flen = riscv_isa_flen (gdbarch);
  CORE_ADDR frame_sp = get_frame_sp (this_frame);
  CORE_ADDR mcontext_base;
  CORE_ADDR regs_base;

  mcontext_base = frame_sp + SIGFRAME_SIGINFO_SIZE + UCONTEXT_MCONTEXT_OFFSET;

  /* Handle the integer registers.  The first one is PC, followed by x1
     through x31.  */
  regs_base = mcontext_base;
  trad_frame_set_reg_addr (this_cache, RISCV_PC_REGNUM, regs_base);
  for (int i = 1; i < 32; i++)
    trad_frame_set_reg_addr (this_cache, RISCV_ZERO_REGNUM + i,
			     regs_base + (i * xlen));

  /* Handle the FP registers.  First comes the 32 FP registers, followed by
     fcsr.  */
  regs_base += 32 * xlen;
  for (int i = 0; i < 32; i++)
    trad_frame_set_reg_addr (this_cache, RISCV_FIRST_FP_REGNUM + i,
			     regs_base + (i * flen));
  regs_base += 32 * flen;
  trad_frame_set_reg_addr (this_cache, RISCV_CSR_FCSR_REGNUM, regs_base);

  /* Choice of the bottom of the sigframe is somewhat arbitrary.  */
  trad_frame_set_id (this_cache, frame_id_build (frame_sp, func));
}

/* Initialize RISC-V Linux ABI info.  */

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

  set_gdbarch_software_single_step (gdbarch, riscv_software_single_step);

  set_solib_svr4_fetch_link_map_offsets (gdbarch,
					 (riscv_isa_xlen (gdbarch) == 4
					  ? svr4_ilp32_fetch_link_map_offsets
					  : svr4_lp64_fetch_link_map_offsets));

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

  /* GNU/Linux uses the dynamic linker included in the GNU C Library.  */
  set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);

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

  set_gdbarch_iterate_over_regset_sections
    (gdbarch, riscv_linux_iterate_over_regset_sections);

  tramp_frame_prepend_unwinder (gdbarch, &riscv_linux_sigframe);
}

/* Initialize RISC-V Linux target support.  */

void _initialize_riscv_linux_tdep ();
void
_initialize_riscv_linux_tdep ()
{
  gdbarch_register_osabi (bfd_arch_riscv, 0, GDB_OSABI_LINUX,
			  riscv_linux_init_abi);
}
