/* Target-dependent code for OpenBSD/amd64.

   Copyright (C) 2003-2013 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 "symtab.h"
#include "objfiles.h"
#include "osabi.h"
#include "regcache.h"
#include "regset.h"
#include "target.h"
#include "trad-frame.h"

#include "gdb_assert.h"
#include "gdb_string.h"

#include "amd64-tdep.h"
#include "i387-tdep.h"
#include "solib-svr4.h"
#include "bsd-uthread.h"

/* Support for core dumps.  */

static void
amd64obsd_supply_regset (const struct regset *regset,
			 struct regcache *regcache, int regnum,
			 const void *regs, size_t len)
{
  const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);

  gdb_assert (len >= tdep->sizeof_gregset + I387_SIZEOF_FXSAVE);

  i386_supply_gregset (regset, regcache, regnum, regs, tdep->sizeof_gregset);
  amd64_supply_fxsave (regcache, regnum,
		       ((const gdb_byte *)regs) + tdep->sizeof_gregset);
}

static const struct regset *
amd64obsd_regset_from_core_section (struct gdbarch *gdbarch,
				    const char *sect_name, size_t sect_size)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  /* OpenBSD core dumps don't use seperate register sets for the
     general-purpose and floating-point registers.  */

  if (strcmp (sect_name, ".reg") == 0
      && sect_size >= tdep->sizeof_gregset + I387_SIZEOF_FXSAVE)
    {
      if (tdep->gregset == NULL)
        tdep->gregset = regset_alloc (gdbarch, amd64obsd_supply_regset, NULL);
      return tdep->gregset;
    }

  return NULL;
}


/* Support for signal handlers.  */

/* Default page size.  */
static const int amd64obsd_page_size = 4096;

/* Return whether THIS_FRAME corresponds to an OpenBSD sigtramp
   routine.  */

static int
amd64obsd_sigtramp_p (struct frame_info *this_frame)
{
  CORE_ADDR pc = get_frame_pc (this_frame);
  CORE_ADDR start_pc = (pc & ~(amd64obsd_page_size - 1));
  const gdb_byte osigreturn[] =
  {
    0x48, 0xc7, 0xc0,
    0x67, 0x00, 0x00, 0x00,	/* movq $SYS_sigreturn, %rax */
    0xcd, 0x80			/* int $0x80 */
  };
  const gdb_byte sigreturn[] =
  {
    0x48, 0xc7, 0xc0,
    0x67, 0x00, 0x00, 0x00,	/* movq $SYS_sigreturn, %rax */
    0x0f, 0x05			/* syscall */
  };
  size_t buflen = (sizeof sigreturn) + 1;
  gdb_byte *buf;
  const char *name;

  /* If the function has a valid symbol name, it isn't a
     trampoline.  */
  find_pc_partial_function (pc, &name, NULL, NULL);
  if (name != NULL)
    return 0;

  /* If the function lives in a valid section (even without a starting
     point) it isn't a trampoline.  */
  if (find_pc_section (pc) != NULL)
    return 0;

  /* If we can't read the instructions at START_PC, return zero.  */
  buf = alloca ((sizeof sigreturn) + 1);
  if (!safe_frame_unwind_memory (this_frame, start_pc + 6, buf, buflen))
    return 0;

  /* Check for sigreturn(2).  Depending on how the assembler encoded
     the `movq %rsp, %rdi' instruction, the code starts at offset 6 or
     7.  OpenBSD 5.0 and later use the `syscall' instruction.  Older
     versions use `int $0x80'.  Check for both.  */
  if (memcmp (buf, sigreturn, sizeof sigreturn)
      && memcmp (buf + 1, sigreturn, sizeof sigreturn)
      && memcmp (buf, osigreturn, sizeof osigreturn)
      && memcmp (buf + 1, osigreturn, sizeof osigreturn))
    return 0;

  return 1;
}

/* Assuming THIS_FRAME is for a BSD sigtramp routine, return the
   address of the associated sigcontext structure.  */

static CORE_ADDR
amd64obsd_sigcontext_addr (struct frame_info *this_frame)
{
  CORE_ADDR pc = get_frame_pc (this_frame);
  ULONGEST offset = (pc & (amd64obsd_page_size - 1));

  /* The %rsp register points at `struct sigcontext' upon entry of a
     signal trampoline.  The relevant part of the trampoline is

        call    *%rax
        movq    %rsp, %rdi
        pushq   %rdi
        movq    $SYS_sigreturn,%rax
        int     $0x80

     (see /usr/src/sys/arch/amd64/amd64/locore.S).  The `pushq'
     instruction clobbers %rsp, but its value is saved in `%rdi'.  */

  if (offset > 5)
    return get_frame_register_unsigned (this_frame, AMD64_RDI_REGNUM);
  else
    return get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM);
}

/* OpenBSD 3.5 or later.  */

/* Mapping between the general-purpose registers in `struct reg'
   format and GDB's register cache layout.  */

/* From <machine/reg.h>.  */
int amd64obsd_r_reg_offset[] =
{
  14 * 8,			/* %rax */
  13 * 8,			/* %rbx */
  3 * 8,			/* %rcx */
  2 * 8,			/* %rdx */
  1 * 8,			/* %rsi */
  0 * 8,			/* %rdi */
  12 * 8,			/* %rbp */
  15 * 8,			/* %rsp */
  4 * 8,			/* %r8 ..  */
  5 * 8,
  6 * 8,
  7 * 8,
  8 * 8,
  9 * 8,
  10 * 8,
  11 * 8,			/* ... %r15 */
  16 * 8,			/* %rip */
  17 * 8,			/* %eflags */
  18 * 8,			/* %cs */
  19 * 8,			/* %ss */
  20 * 8,			/* %ds */
  21 * 8,			/* %es */
  22 * 8,			/* %fs */
  23 * 8			/* %gs */
};

/* From <machine/signal.h>.  */
static int amd64obsd_sc_reg_offset[] =
{
  14 * 8,			/* %rax */
  13 * 8,			/* %rbx */
  3 * 8,			/* %rcx */
  2 * 8,			/* %rdx */
  1 * 8,			/* %rsi */
  0 * 8,			/* %rdi */
  12 * 8,			/* %rbp */
  24 * 8,			/* %rsp */
  4 * 8,			/* %r8 ...  */
  5 * 8,
  6 * 8,
  7 * 8,
  8 * 8,
  9 * 8,
  10 * 8,
  11 * 8,			/* ... %r15 */
  21 * 8,			/* %rip */
  23 * 8,			/* %eflags */
  22 * 8,			/* %cs */
  25 * 8,			/* %ss */
  18 * 8,			/* %ds */
  17 * 8,			/* %es */
  16 * 8,			/* %fs */
  15 * 8			/* %gs */
};

/* From /usr/src/lib/libpthread/arch/amd64/uthread_machdep.c.  */
static int amd64obsd_uthread_reg_offset[] =
{
  19 * 8,			/* %rax */
  16 * 8,			/* %rbx */
  18 * 8,			/* %rcx */
  17 * 8,			/* %rdx */
  14 * 8,			/* %rsi */
  13 * 8,			/* %rdi */
  15 * 8,			/* %rbp */
  -1,				/* %rsp */
  12 * 8,			/* %r8 ...  */
  11 * 8,
  10 * 8,
  9 * 8,
  8 * 8,
  7 * 8,
  6 * 8,
  5 * 8,			/* ... %r15 */
  20 * 8,			/* %rip */
  4 * 8,			/* %eflags */
  21 * 8,			/* %cs */
  -1,				/* %ss */
  3 * 8,			/* %ds */
  2 * 8,			/* %es */
  1 * 8,			/* %fs */
  0 * 8				/* %gs */
};

/* Offset within the thread structure where we can find the saved
   stack pointer (%esp).  */
#define AMD64OBSD_UTHREAD_RSP_OFFSET	400

static void
amd64obsd_supply_uthread (struct regcache *regcache,
			  int regnum, CORE_ADDR addr)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR sp_addr = addr + AMD64OBSD_UTHREAD_RSP_OFFSET;
  CORE_ADDR sp = 0;
  gdb_byte buf[8];
  int i;

  gdb_assert (regnum >= -1);

  if (regnum == -1 || regnum == AMD64_RSP_REGNUM)
    {
      int offset;

      /* Fetch stack pointer from thread structure.  */
      sp = read_memory_unsigned_integer (sp_addr, 8, byte_order);

      /* Adjust the stack pointer such that it looks as if we just
         returned from _thread_machdep_switch.  */
      offset = amd64obsd_uthread_reg_offset[AMD64_RIP_REGNUM] + 8;
      store_unsigned_integer (buf, 8, byte_order, sp + offset);
      regcache_raw_supply (regcache, AMD64_RSP_REGNUM, buf);
    }

  for (i = 0; i < ARRAY_SIZE (amd64obsd_uthread_reg_offset); i++)
    {
      if (amd64obsd_uthread_reg_offset[i] != -1
	  && (regnum == -1 || regnum == i))
	{
	  /* Fetch stack pointer from thread structure (if we didn't
             do so already).  */
	  if (sp == 0)
	    sp = read_memory_unsigned_integer (sp_addr, 8, byte_order);

	  /* Read the saved register from the stack frame.  */
	  read_memory (sp + amd64obsd_uthread_reg_offset[i], buf, 8);
	  regcache_raw_supply (regcache, i, buf);
	}
    }
}

static void
amd64obsd_collect_uthread (const struct regcache *regcache,
			   int regnum, CORE_ADDR addr)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR sp_addr = addr + AMD64OBSD_UTHREAD_RSP_OFFSET;
  CORE_ADDR sp = 0;
  gdb_byte buf[8];
  int i;

  gdb_assert (regnum >= -1);

  if (regnum == -1 || regnum == AMD64_RSP_REGNUM)
    {
      int offset;

      /* Calculate the stack pointer (frame pointer) that will be
         stored into the thread structure.  */
      offset = amd64obsd_uthread_reg_offset[AMD64_RIP_REGNUM] + 8;
      regcache_raw_collect (regcache, AMD64_RSP_REGNUM, buf);
      sp = extract_unsigned_integer (buf, 8, byte_order) - offset;

      /* Store the stack pointer.  */
      write_memory_unsigned_integer (sp_addr, 8, byte_order, sp);

      /* The stack pointer was (potentially) modified.  Make sure we
         build a proper stack frame.  */
      regnum = -1;
    }

  for (i = 0; i < ARRAY_SIZE (amd64obsd_uthread_reg_offset); i++)
    {
      if (amd64obsd_uthread_reg_offset[i] != -1
	  && (regnum == -1 || regnum == i))
	{
	  /* Fetch stack pointer from thread structure (if we didn't
             calculate it already).  */
	  if (sp == 0)
	    sp = read_memory_unsigned_integer (sp_addr, 8, byte_order);

	  /* Write the register into the stack frame.  */
	  regcache_raw_collect (regcache, i, buf);
	  write_memory (sp + amd64obsd_uthread_reg_offset[i], buf, 8);
	}
    }
}
/* Kernel debugging support.  */

/* From <machine/frame.h>.  Easy since `struct trapframe' matches
   `struct sigcontext'.  */
#define amd64obsd_tf_reg_offset amd64obsd_sc_reg_offset

static struct trad_frame_cache *
amd64obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct trad_frame_cache *cache;
  CORE_ADDR func, sp, addr;
  ULONGEST cs;
  const char *name;
  int i;

  if (*this_cache)
    return *this_cache;

  cache = trad_frame_cache_zalloc (this_frame);
  *this_cache = cache;

  func = get_frame_func (this_frame);
  sp = get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM);

  find_pc_partial_function (func, &name, NULL, NULL);
  if (name && strncmp (name, "Xintr", 5) == 0)
    addr = sp + 8;		/* It's an interrupt frame.  */
  else
    addr = sp;

  for (i = 0; i < ARRAY_SIZE (amd64obsd_tf_reg_offset); i++)
    if (amd64obsd_tf_reg_offset[i] != -1)
      trad_frame_set_reg_addr (cache, i, addr + amd64obsd_tf_reg_offset[i]);

  /* Read %cs from trap frame.  */
  addr += amd64obsd_tf_reg_offset[AMD64_CS_REGNUM];
  cs = read_memory_unsigned_integer (addr, 8, byte_order);
  if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
    {
      /* Trap from user space; terminate backtrace.  */
      trad_frame_set_id (cache, outer_frame_id);
    }
  else
    {
      /* Construct the frame ID using the function start.  */
      trad_frame_set_id (cache, frame_id_build (sp + 16, func));
    }

  return cache;
}

static void
amd64obsd_trapframe_this_id (struct frame_info *this_frame,
			     void **this_cache, struct frame_id *this_id)
{
  struct trad_frame_cache *cache =
    amd64obsd_trapframe_cache (this_frame, this_cache);
  
  trad_frame_get_id (cache, this_id);
}

static struct value *
amd64obsd_trapframe_prev_register (struct frame_info *this_frame,
				   void **this_cache, int regnum)
{
  struct trad_frame_cache *cache =
    amd64obsd_trapframe_cache (this_frame, this_cache);

  return trad_frame_get_register (cache, this_frame, regnum);
}

static int
amd64obsd_trapframe_sniffer (const struct frame_unwind *self,
			     struct frame_info *this_frame,
			     void **this_prologue_cache)
{
  ULONGEST cs;
  const char *name;

  /* Check Current Privilege Level and bail out if we're not executing
     in kernel space.  */
  cs = get_frame_register_unsigned (this_frame, AMD64_CS_REGNUM);
  if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
    return 0;

  find_pc_partial_function (get_frame_pc (this_frame), &name, NULL, NULL);
  return (name && ((strcmp (name, "calltrap") == 0)
		   || (strcmp (name, "osyscall1") == 0)
		   || (strcmp (name, "Xsyscall") == 0)
		   || (strncmp (name, "Xintr", 5) == 0)));
}

static const struct frame_unwind amd64obsd_trapframe_unwind = {
  /* FIXME: kettenis/20051219: This really is more like an interrupt
     frame, but SIGTRAMP_FRAME would print <signal handler called>,
     which really is not what we want here.  */
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  amd64obsd_trapframe_this_id,
  amd64obsd_trapframe_prev_register,
  NULL,
  amd64obsd_trapframe_sniffer
};


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

  amd64_init_abi (info, gdbarch);

  /* Initialize general-purpose register set details.  */
  tdep->gregset_reg_offset = amd64obsd_r_reg_offset;
  tdep->gregset_num_regs = ARRAY_SIZE (amd64obsd_r_reg_offset);
  tdep->sizeof_gregset = 24 * 8;

  tdep->jb_pc_offset = 7 * 8;

  tdep->sigtramp_p = amd64obsd_sigtramp_p;
  tdep->sigcontext_addr = amd64obsd_sigcontext_addr;
  tdep->sc_reg_offset = amd64obsd_sc_reg_offset;
  tdep->sc_num_regs = ARRAY_SIZE (amd64obsd_sc_reg_offset);

  /* OpenBSD provides a user-level threads implementation.  */
  bsd_uthread_set_supply_uthread (gdbarch, amd64obsd_supply_uthread);
  bsd_uthread_set_collect_uthread (gdbarch, amd64obsd_collect_uthread);

  /* OpenBSD uses SVR4-style shared libraries.  */
  set_solib_svr4_fetch_link_map_offsets
    (gdbarch, svr4_lp64_fetch_link_map_offsets);

  /* Unwind kernel trap frames correctly.  */
  frame_unwind_prepend_unwinder (gdbarch, &amd64obsd_trapframe_unwind);
}

/* Traditional (a.out) NetBSD-style core dumps.  */

static void
amd64obsd_core_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  amd64obsd_init_abi (info, gdbarch);

  set_gdbarch_regset_from_core_section
    (gdbarch, amd64obsd_regset_from_core_section);
}


/* Provide a prototype to silence -Wmissing-prototypes.  */
void _initialize_amd64obsd_tdep (void);

void
_initialize_amd64obsd_tdep (void)
{
  /* The OpenBSD/amd64 native dependent code makes this assumption.  */
  gdb_assert (ARRAY_SIZE (amd64obsd_r_reg_offset) == AMD64_NUM_GREGS);

  gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
			  GDB_OSABI_OPENBSD_ELF, amd64obsd_init_abi);

  /* OpenBSD uses traditional (a.out) NetBSD-style core dumps.  */
  gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
			  GDB_OSABI_NETBSD_AOUT, amd64obsd_core_init_abi);
}
