/* Target-dependent code for FreeBSD/arm.

   Copyright (C) 2017-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 "elf/common.h"
#include "arm-tdep.h"
#include "arm-fbsd-tdep.h"
#include "auxv.h"
#include "fbsd-tdep.h"
#include "gdbcore.h"
#include "osabi.h"
#include "solib-svr4.h"
#include "trad-frame.h"
#include "tramp-frame.h"

/* In a signal frame, sp points to a 'struct sigframe' which is
   defined as:

   struct sigframe {
	   siginfo_t	sf_si;
	   ucontext_t	sf_uc;
	   mcontext_vfp_t sf_vfp;
   };

   ucontext_t is defined as:

   struct __ucontext {
	   sigset_t	uc_sigmask;
	   mcontext_t	uc_mcontext;
	   ...
   };

   mcontext_t is defined as:

   struct {
	   unsigned int __gregs[17];
	   size_t       mc_vfp_size;
	   void         *mc_vfp_ptr;
	   ...
   };

   mcontext_vfp_t is defined as:

   struct {
	  uint64_t      mcv_reg[32];
	  uint32_t      mcv_fpscr;
   };

   If the VFP state is valid, then mc_vfp_ptr will point to sf_vfp in
   the sigframe, otherwise it is NULL.  There is no non-VFP floating
   point register state saved in the signal frame.  */

#define ARM_MCONTEXT_REG_SIZE		4
#define ARM_MCONTEXT_VFP_REG_SIZE	8
#define ARM_SIGFRAME_UCONTEXT_OFFSET	64
#define ARM_UCONTEXT_MCONTEXT_OFFSET	16
#define ARM_MCONTEXT_VFP_PTR_OFFSET	72

/* Implement the "init" method of struct tramp_frame.  */

static void
arm_fbsd_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);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM);
  CORE_ADDR mcontext_addr = (sp
			     + ARM_SIGFRAME_UCONTEXT_OFFSET
			     + ARM_UCONTEXT_MCONTEXT_OFFSET);
  ULONGEST mcontext_vfp_addr;

  for (int i = 0; i < 16; i++)
    {
      trad_frame_set_reg_addr (this_cache,
			       ARM_A1_REGNUM + i,
			       mcontext_addr + i * ARM_MCONTEXT_REG_SIZE);
    }
  trad_frame_set_reg_addr (this_cache, ARM_PS_REGNUM,
			   mcontext_addr + 16 * ARM_MCONTEXT_REG_SIZE);

  if (safe_read_memory_unsigned_integer (mcontext_addr
					 + ARM_MCONTEXT_VFP_PTR_OFFSET, 4,
					 byte_order,
					 &mcontext_vfp_addr)
      && mcontext_vfp_addr != 0)
    {
      for (int i = 0; i < 32; i++)
	{
	  trad_frame_set_reg_addr (this_cache, ARM_D0_REGNUM + i,
				   mcontext_vfp_addr
				   + i * ARM_MCONTEXT_VFP_REG_SIZE);
	}
      trad_frame_set_reg_addr (this_cache, ARM_FPSCR_REGNUM,
			       mcontext_vfp_addr
			       + 32 * ARM_MCONTEXT_VFP_REG_SIZE);
    }

  trad_frame_set_id (this_cache, frame_id_build (sp, func));
}

static const struct tramp_frame arm_fbsd_sigframe =
{
  SIGTRAMP_FRAME,
  4,
  {
    {0xe1a0000d, -1},		/* mov  r0, sp  */
    {0xe2800040, -1},		/* add  r0, r0, #SIGF_UC  */
    {0xe59f700c, -1},		/* ldr  r7, [pc, #12]  */
    {0xef0001a1, -1},		/* swi  SYS_sigreturn  */
    {TRAMP_SENTINEL_INSN, -1}
  },
  arm_fbsd_sigframe_init
};

/* Register maps.  */

static const struct regcache_map_entry arm_fbsd_gregmap[] =
  {
    { 13, ARM_A1_REGNUM, 4 }, /* r0 ... r12 */
    { 1, ARM_SP_REGNUM, 4 },
    { 1, ARM_LR_REGNUM, 4 },
    { 1, ARM_PC_REGNUM, 4 },
    { 1, ARM_PS_REGNUM, 4 },
    { 0 }
  };

static const struct regcache_map_entry arm_fbsd_vfpregmap[] =
  {
    { 32, ARM_D0_REGNUM, 8 }, /* d0 ... d31 */
    { 1, ARM_FPSCR_REGNUM, 4 },
    { 0 }
  };

/* Register set definitions.  */

const struct regset arm_fbsd_gregset =
  {
    arm_fbsd_gregmap,
    regcache_supply_regset, regcache_collect_regset
  };

const struct regset arm_fbsd_vfpregset =
  {
    arm_fbsd_vfpregmap,
    regcache_supply_regset, regcache_collect_regset
  };

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

static void
arm_fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
				       iterate_over_regset_sections_cb *cb,
				       void *cb_data,
				       const struct regcache *regcache)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  cb (".reg", ARM_FBSD_SIZEOF_GREGSET, &arm_fbsd_gregset, NULL, cb_data);

  /* While FreeBSD/arm cores do contain a NT_FPREGSET / ".reg2"
     register set, it is not populated with register values by the
     kernel but just contains all zeroes.  */
  if (tdep->vfp_register_count > 0)
    cb (".reg-arm-vfp", ARM_FBSD_SIZEOF_VFPREGSET, &arm_fbsd_vfpregset,
	"VFP floating-point", cb_data);
}

/* Lookup a target description from a target's AT_HWCAP auxiliary
   vector.  */

const struct target_desc *
arm_fbsd_read_description_auxv (struct target_ops *target)
{
  CORE_ADDR arm_hwcap = 0;

  if (target_auxv_search (target, AT_FREEBSD_HWCAP, &arm_hwcap) != 1)
    return NULL;

  if (arm_hwcap & HWCAP_VFP)
    {
      if (arm_hwcap & HWCAP_NEON)
	return tdesc_arm_with_neon;
      else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPD32))
	  == (HWCAP_VFPv3 | HWCAP_VFPD32))
	return tdesc_arm_with_vfpv3;
      else
	return tdesc_arm_with_vfpv2;
    }

  return NULL;
}

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

static const struct target_desc *
arm_fbsd_core_read_description (struct gdbarch *gdbarch,
				struct target_ops *target,
				bfd *abfd)
{
  return arm_fbsd_read_description_auxv (target);
}

/* Implement the 'init_osabi' method of struct gdb_osabi_handler.  */

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

  /* Generic FreeBSD support.  */
  fbsd_init_abi (info, gdbarch);

  if (tdep->fp_model == ARM_FLOAT_AUTO)
    tdep->fp_model = ARM_FLOAT_SOFT_VFP;

  tramp_frame_prepend_unwinder (gdbarch, &arm_fbsd_sigframe);

  set_solib_svr4_fetch_link_map_offsets
    (gdbarch, svr4_ilp32_fetch_link_map_offsets);

  tdep->jb_pc = 24;
  tdep->jb_elt_size = 4;

  set_gdbarch_iterate_over_regset_sections
    (gdbarch, arm_fbsd_iterate_over_regset_sections);
  set_gdbarch_core_read_description (gdbarch, arm_fbsd_core_read_description);

  /* Single stepping.  */
  set_gdbarch_software_single_step (gdbarch, arm_software_single_step);
}

void
_initialize_arm_fbsd_tdep (void)
{
  gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_FREEBSD,
			  arm_fbsd_init_abi);
}
