/* Target-dependent code for OpenBSD/sparc.

   Copyright (C) 2004-2020 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 "gdbcore.h"
#include "osabi.h"
#include "regcache.h"
#include "symtab.h"
#include "trad-frame.h"

#include "obsd-tdep.h"
#include "sparc-tdep.h"
#include "solib-svr4.h"
#include "bsd-uthread.h"
#include "gdbarch.h"

/* Signal trampolines.  */

/* The OpenBSD kernel maps the signal trampoline at some random
   location in user space, which means that the traditional BSD way of
   detecting it won't work.

   The signal trampoline will be mapped at an address that is page
   aligned.  We recognize the signal trampoline by looking for the
   sigreturn system call.  */

static const int sparc32obsd_page_size = 4096;

static int
sparc32obsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
{
  CORE_ADDR start_pc = (pc & ~(sparc32obsd_page_size - 1));
  unsigned long insn;

  if (name)
    return 0;

  /* Check for "restore %g0, SYS_sigreturn, %g1".  */
  insn = sparc_fetch_instruction (start_pc + 0xec);
  if (insn != 0x83e82067)
    return 0;

  /* Check for "t ST_SYSCALL".  */
  insn = sparc_fetch_instruction (start_pc + 0xf4);
  if (insn != 0x91d02000)
    return 0;

  return 1;
}

static struct sparc_frame_cache *
sparc32obsd_sigtramp_frame_cache (struct frame_info *this_frame,
				  void **this_cache)
{
  struct sparc_frame_cache *cache;
  CORE_ADDR addr;

  if (*this_cache)
    return (struct sparc_frame_cache *) *this_cache;

  cache = sparc_frame_cache (this_frame, this_cache);
  gdb_assert (cache == *this_cache);

  /* If we couldn't find the frame's function, we're probably dealing
     with an on-stack signal trampoline.  */
  if (cache->pc == 0)
    {
      cache->pc = get_frame_pc (this_frame);
      cache->pc &= ~(sparc32obsd_page_size - 1);

      /* Since we couldn't find the frame's function, the cache was
	 initialized under the assumption that we're frameless.  */
      sparc_record_save_insn (cache);
      addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
      cache->base = addr;
    }

  cache->saved_regs = sparc32nbsd_sigcontext_saved_regs (this_frame);

  return cache;
}

static void
sparc32obsd_sigtramp_frame_this_id (struct frame_info *this_frame,
				    void **this_cache,
				    struct frame_id *this_id)
{
  struct sparc_frame_cache *cache =
    sparc32obsd_sigtramp_frame_cache (this_frame, this_cache);

  (*this_id) = frame_id_build (cache->base, cache->pc);
}

static struct value *
sparc32obsd_sigtramp_frame_prev_register (struct frame_info *this_frame,
					  void **this_cache, int regnum)
{
  struct sparc_frame_cache *cache =
    sparc32obsd_sigtramp_frame_cache (this_frame, this_cache);

  return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
}

static int
sparc32obsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
				    struct frame_info *this_frame,
				    void **this_cache)
{
  CORE_ADDR pc = get_frame_pc (this_frame);
  const char *name;

  find_pc_partial_function (pc, &name, NULL, NULL);
  if (sparc32obsd_pc_in_sigtramp (pc, name))
    return 1;

  return 0;
}
static const struct frame_unwind sparc32obsd_sigtramp_frame_unwind =
{
  SIGTRAMP_FRAME,
  default_frame_unwind_stop_reason,
  sparc32obsd_sigtramp_frame_this_id,
  sparc32obsd_sigtramp_frame_prev_register,
  NULL,
  sparc32obsd_sigtramp_frame_sniffer
};



/* Offset wthin the thread structure where we can find %fp and %i7.  */
#define SPARC32OBSD_UTHREAD_FP_OFFSET	128
#define SPARC32OBSD_UTHREAD_PC_OFFSET	132

static void
sparc32obsd_supply_uthread (struct regcache *regcache,
			    int regnum, CORE_ADDR addr)
{
  struct gdbarch *gdbarch = regcache->arch ();
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR fp, fp_addr = addr + SPARC32OBSD_UTHREAD_FP_OFFSET;
  gdb_byte buf[4];

  gdb_assert (regnum >= -1);

  fp = read_memory_unsigned_integer (fp_addr, 4, byte_order);
  if (regnum == SPARC_SP_REGNUM || regnum == -1)
    {
      store_unsigned_integer (buf, 4, byte_order, fp);
      regcache->raw_supply (SPARC_SP_REGNUM, buf);

      if (regnum == SPARC_SP_REGNUM)
	return;
    }

  if (regnum == SPARC32_PC_REGNUM || regnum == SPARC32_NPC_REGNUM
      || regnum == -1)
    {
      CORE_ADDR i7, i7_addr = addr + SPARC32OBSD_UTHREAD_PC_OFFSET;

      i7 = read_memory_unsigned_integer (i7_addr, 4, byte_order);
      if (regnum == SPARC32_PC_REGNUM || regnum == -1)
	{
	  store_unsigned_integer (buf, 4, byte_order, i7 + 8);
	  regcache->raw_supply (SPARC32_PC_REGNUM, buf);
	}
      if (regnum == SPARC32_NPC_REGNUM || regnum == -1)
	{
	  store_unsigned_integer (buf, 4, byte_order, i7 + 12);
	  regcache->raw_supply (SPARC32_NPC_REGNUM, buf);
	}

      if (regnum == SPARC32_PC_REGNUM || regnum == SPARC32_NPC_REGNUM)
	return;
    }

  sparc_supply_rwindow (regcache, fp, regnum);
}

static void
sparc32obsd_collect_uthread(const struct regcache *regcache,
			    int regnum, CORE_ADDR addr)
{
  struct gdbarch *gdbarch = regcache->arch ();
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR sp;
  gdb_byte buf[4];

  gdb_assert (regnum >= -1);

  if (regnum == SPARC_SP_REGNUM || regnum == -1)
    {
      CORE_ADDR fp_addr = addr + SPARC32OBSD_UTHREAD_FP_OFFSET;

      regcache->raw_collect (SPARC_SP_REGNUM, buf);
      write_memory (fp_addr,buf, 4);
    }

  if (regnum == SPARC32_PC_REGNUM || regnum == -1)
    {
      CORE_ADDR i7, i7_addr = addr + SPARC32OBSD_UTHREAD_PC_OFFSET;

      regcache->raw_collect (SPARC32_PC_REGNUM, buf);
      i7 = extract_unsigned_integer (buf, 4, byte_order) - 8;
      write_memory_unsigned_integer (i7_addr, 4, byte_order, i7);

      if (regnum == SPARC32_PC_REGNUM)
	return;
    }

  regcache->raw_collect (SPARC_SP_REGNUM, buf);
  sp = extract_unsigned_integer (buf, 4, byte_order);
  sparc_collect_rwindow (regcache, sp, regnum);
}


static void
sparc32obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  /* OpenBSD/sparc is very similar to NetBSD/sparc ELF.  */
  sparc32nbsd_init_abi (info, gdbarch);

  set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);

  frame_unwind_append_unwinder (gdbarch, &sparc32obsd_sigtramp_frame_unwind);

  /* OpenBSD provides a user-level threads implementation.  */
  bsd_uthread_set_supply_uthread (gdbarch, sparc32obsd_supply_uthread);
  bsd_uthread_set_collect_uthread (gdbarch, sparc32obsd_collect_uthread);
}

void _initialize_sparc32obsd_tdep ();
void
_initialize_sparc32obsd_tdep ()
{
  gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_OPENBSD,
			  sparc32obsd_init_abi);
}
