/* Target-dependent code for GNU/Linux on Tilera TILE-Gx processors.

   Copyright (C) 2012-2016 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 "osabi.h"
#include "linux-tdep.h"
#include "glibc-tdep.h"
#include "solib-svr4.h"
#include "symtab.h"
#include "regcache.h"
#include "regset.h"
#include "tramp-frame.h"
#include "trad-frame.h"
#include "tilegx-tdep.h"

/* Signal trampoline support.  */

static void
tilegx_linux_sigframe_init (const struct tramp_frame *self,
			    struct frame_info *this_frame,
			    struct trad_frame_cache *this_cache,
			    CORE_ADDR func)
{
  CORE_ADDR sp = get_frame_register_unsigned (this_frame, 54);

  /* Base address of register save area.  */
  CORE_ADDR base = sp
                   + 16    /* Skip ABI_SAVE_AREA.  */
                   + 128   /* Skip SIGINFO.  */
                   + 40;   /* Skip UCONTEXT.  */

  /* Address of saved LR register (R56) which holds previous PC.  */
  CORE_ADDR prev_pc = base + 56 * 8;

  int i;

  for (i = 0; i < 56; i++)
    trad_frame_set_reg_addr (this_cache, i, base + i * 8);

  trad_frame_set_reg_value (this_cache, 64,
                            get_frame_memory_unsigned (this_frame, prev_pc, 8));

  /* Save a frame ID.  */
  trad_frame_set_id (this_cache, frame_id_build (base, func));
}

static const struct tramp_frame tilegx_linux_rt_sigframe =
{
  SIGTRAMP_FRAME,
  8,
  {
    { 0x00045fe551483000ULL, -1 }, /* { moveli r10, 139 } */
    { 0x286b180051485000ULL, -1 }, /* { swint1 } */
    { TRAMP_SENTINEL_INSN, -1 }
  },
  tilegx_linux_sigframe_init
};

/* Register map; must match struct pt_regs in "ptrace.h".  */

static const struct regcache_map_entry tilegx_linux_regmap[] =
  {
    { TILEGX_NUM_EASY_REGS, TILEGX_FIRST_EASY_REGNUM, 8 },
    { 1, TILEGX_PC_REGNUM, 8 },
    { 1, TILEGX_FAULTNUM_REGNUM, 8 },
    { 0 }
  };

#define TILEGX_LINUX_SIZEOF_GREGSET (64 * 8)

/* TILE-Gx Linux kernel register set.  */

static const struct regset tilegx_linux_regset =
{
  tilegx_linux_regmap,
  regcache_supply_regset, regcache_collect_regset
};


static void
tilegx_iterate_over_regset_sections (struct gdbarch *gdbarch,
				     iterate_over_regset_sections_cb *cb,
				     void *cb_data,
				     const struct regcache *regcache)
{
  cb (".reg", TILEGX_LINUX_SIZEOF_GREGSET, &tilegx_linux_regset,
      NULL, cb_data);
}

/* OS specific initialization of gdbarch.  */

static void
tilegx_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  int arch_size = gdbarch_addr_bit (gdbarch);

  linux_init_abi (info, gdbarch);

  tramp_frame_prepend_unwinder (gdbarch, &tilegx_linux_rt_sigframe);

  set_gdbarch_iterate_over_regset_sections
    (gdbarch, tilegx_iterate_over_regset_sections);

  /* GNU/Linux uses SVR4-style shared libraries.  */
  if (arch_size == 32)
    set_solib_svr4_fetch_link_map_offsets (gdbarch,
					   svr4_ilp32_fetch_link_map_offsets);
  else
    set_solib_svr4_fetch_link_map_offsets (gdbarch,
					   svr4_lp64_fetch_link_map_offsets);

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

  /* Shared library handling.  */
  set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
  set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
}

/* Provide a prototype to silence -Wmissing-prototypes.  */
extern initialize_file_ftype _initialize_tilegx_linux_tdep;

void
_initialize_tilegx_linux_tdep (void)
{
  gdbarch_register_osabi (bfd_arch_tilegx, bfd_mach_tilegx, GDB_OSABI_LINUX,
			  tilegx_linux_init_abi);
}
