/* Native-dependent code for GNU/Linux x86-64.

   Copyright (C) 2001-2018 Free Software Foundation, Inc.
   Contributed by Jiri Smid, SuSE Labs.

   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 "inferior.h"
#include "regcache.h"
#include "elf/common.h"
#include <sys/uio.h>
#include "nat/gdb_ptrace.h"
#include <asm/prctl.h>
#include <sys/reg.h>
#include "gregset.h"
#include "gdb_proc_service.h"

#include "amd64-nat.h"
#include "linux-nat.h"
#include "amd64-tdep.h"
#include "amd64-linux-tdep.h"
#include "i386-linux-tdep.h"
#include "x86-xstate.h"

#include "x86-linux-nat.h"
#include "nat/linux-ptrace.h"
#include "nat/amd64-linux-siginfo.h"

/* This definition comes from prctl.h.  Kernels older than 2.5.64
   do not have it.  */
#ifndef PTRACE_ARCH_PRCTL
#define PTRACE_ARCH_PRCTL      30
#endif

/* Mapping between the general-purpose registers in GNU/Linux x86-64
   `struct user' format and GDB's register cache layout for GNU/Linux
   i386.

   Note that most GNU/Linux x86-64 registers are 64-bit, while the
   GNU/Linux i386 registers are all 32-bit, but since we're
   little-endian we get away with that.  */

/* From <sys/reg.h> on GNU/Linux i386.  */
static int amd64_linux_gregset32_reg_offset[] =
{
  RAX * 8, RCX * 8,		/* %eax, %ecx */
  RDX * 8, RBX * 8,		/* %edx, %ebx */
  RSP * 8, RBP * 8,		/* %esp, %ebp */
  RSI * 8, RDI * 8,		/* %esi, %edi */
  RIP * 8, EFLAGS * 8,		/* %eip, %eflags */
  CS * 8, SS * 8,		/* %cs, %ss */
  DS * 8, ES * 8,		/* %ds, %es */
  FS * 8, GS * 8,		/* %fs, %gs */
  -1, -1, -1, -1, -1, -1, -1, -1,
  -1, -1, -1, -1, -1, -1, -1, -1,
  -1, -1, -1, -1, -1, -1, -1, -1, -1,
  -1, -1, -1, -1, -1, -1, -1, -1,
  -1, -1, -1, -1,		  /* MPX registers BND0 ... BND3.  */
  -1, -1,			  /* MPX registers BNDCFGU, BNDSTATUS.  */
  -1, -1, -1, -1, -1, -1, -1, -1, /* k0 ... k7 (AVX512)  */
  -1, -1, -1, -1, -1, -1, -1, -1, /* zmm0 ... zmm7 (AVX512)  */
  -1,				  /* PKEYS register PKRU  */
  ORIG_RAX * 8			  /* "orig_eax"  */
};


/* Transfering the general-purpose registers between GDB, inferiors
   and core files.  */

/* Fill GDB's register cache with the general-purpose register values
   in *GREGSETP.  */

void
supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp)
{
  amd64_supply_native_gregset (regcache, gregsetp, -1);
}

/* Fill register REGNUM (if it is a general-purpose register) in
   *GREGSETP with the value in GDB's register cache.  If REGNUM is -1,
   do this for all registers.  */

void
fill_gregset (const struct regcache *regcache,
	      elf_gregset_t *gregsetp, int regnum)
{
  amd64_collect_native_gregset (regcache, gregsetp, regnum);
}

/* Transfering floating-point registers between GDB, inferiors and cores.  */

/* Fill GDB's register cache with the floating-point and SSE register
   values in *FPREGSETP.  */

void
supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
{
  amd64_supply_fxsave (regcache, -1, fpregsetp);
}

/* Fill register REGNUM (if it is a floating-point or SSE register) in
   *FPREGSETP with the value in GDB's register cache.  If REGNUM is
   -1, do this for all registers.  */

void
fill_fpregset (const struct regcache *regcache,
	       elf_fpregset_t *fpregsetp, int regnum)
{
  amd64_collect_fxsave (regcache, regnum, fpregsetp);
}


/* Transferring arbitrary registers between GDB and inferior.  */

/* Fetch register REGNUM from the child process.  If REGNUM is -1, do
   this for all registers (including the floating point and SSE
   registers).  */

static void
amd64_linux_fetch_inferior_registers (struct target_ops *ops,
				      struct regcache *regcache, int regnum)
{
  struct gdbarch *gdbarch = regcache->arch ();
  int tid;

  /* GNU/Linux LWP ID's are process ID's.  */
  tid = ptid_get_lwp (regcache_get_ptid (regcache));
  if (tid == 0)
    tid = ptid_get_pid (regcache_get_ptid (regcache)); /* Not a threaded program.  */

  if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
    {
      elf_gregset_t regs;

      if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
	perror_with_name (_("Couldn't get registers"));

      amd64_supply_native_gregset (regcache, &regs, -1);
      if (regnum != -1)
	return;
    }

  if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
    {
      elf_fpregset_t fpregs;

      if (have_ptrace_getregset == TRIBOOL_TRUE)
	{
	  char xstateregs[X86_XSTATE_MAX_SIZE];
	  struct iovec iov;

	  iov.iov_base = xstateregs;
	  iov.iov_len = sizeof (xstateregs);
	  if (ptrace (PTRACE_GETREGSET, tid,
		      (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
	    perror_with_name (_("Couldn't get extended state status"));

	  amd64_supply_xsave (regcache, -1, xstateregs);
	}
      else
	{
	  if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
	    perror_with_name (_("Couldn't get floating point status"));

	  amd64_supply_fxsave (regcache, -1, &fpregs);
	}
#ifndef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE
      {
	/* PTRACE_ARCH_PRCTL is obsolete since 2.6.25, where the
	   fs_base and gs_base fields of user_regs_struct can be
	   used directly.  */
	unsigned long base;

	if (regnum == -1 || regnum == AMD64_FSBASE_REGNUM)
	  {
	    if (ptrace (PTRACE_ARCH_PRCTL, tid, &base, ARCH_GET_FS) < 0)
	      perror_with_name (_("Couldn't get segment register fs_base"));

	    regcache_raw_supply (regcache, AMD64_FSBASE_REGNUM, &base);
	  }

	if (regnum == -1 || regnum == AMD64_GSBASE_REGNUM)
	  {
	    if (ptrace (PTRACE_ARCH_PRCTL, tid, &base, ARCH_GET_GS) < 0)
	      perror_with_name (_("Couldn't get segment register gs_base"));

	    regcache_raw_supply (regcache, AMD64_GSBASE_REGNUM, &base);
	  }
      }
#endif
    }
}

/* Store register REGNUM back into the child process.  If REGNUM is
   -1, do this for all registers (including the floating-point and SSE
   registers).  */

static void
amd64_linux_store_inferior_registers (struct target_ops *ops,
				      struct regcache *regcache, int regnum)
{
  struct gdbarch *gdbarch = regcache->arch ();
  int tid;

  /* GNU/Linux LWP ID's are process ID's.  */
  tid = ptid_get_lwp (regcache_get_ptid (regcache));
  if (tid == 0)
    tid = ptid_get_pid (regcache_get_ptid (regcache)); /* Not a threaded program.  */

  if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
    {
      elf_gregset_t regs;

      if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
	perror_with_name (_("Couldn't get registers"));

      amd64_collect_native_gregset (regcache, &regs, regnum);

      if (ptrace (PTRACE_SETREGS, tid, 0, (long) &regs) < 0)
	perror_with_name (_("Couldn't write registers"));

      if (regnum != -1)
	return;
    }

  if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
    {
      elf_fpregset_t fpregs;

      if (have_ptrace_getregset == TRIBOOL_TRUE)
	{
	  char xstateregs[X86_XSTATE_MAX_SIZE];
	  struct iovec iov;

	  iov.iov_base = xstateregs;
	  iov.iov_len = sizeof (xstateregs);
	  if (ptrace (PTRACE_GETREGSET, tid,
		      (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
	    perror_with_name (_("Couldn't get extended state status"));

	  amd64_collect_xsave (regcache, regnum, xstateregs, 0);

	  if (ptrace (PTRACE_SETREGSET, tid,
		      (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
	    perror_with_name (_("Couldn't write extended state status"));
	}
      else
	{
	  if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
	    perror_with_name (_("Couldn't get floating point status"));

	  amd64_collect_fxsave (regcache, regnum, &fpregs);

	  if (ptrace (PTRACE_SETFPREGS, tid, 0, (long) &fpregs) < 0)
	    perror_with_name (_("Couldn't write floating point status"));
	}

#ifndef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE
      {
	/* PTRACE_ARCH_PRCTL is obsolete since 2.6.25, where the
	   fs_base and gs_base fields of user_regs_struct can be
	   used directly.  */
	void *base;

	if (regnum == -1 || regnum == AMD64_FSBASE_REGNUM)
	  {
	    regcache_raw_collect (regcache, AMD64_FSBASE_REGNUM, &base);

	    if (ptrace (PTRACE_ARCH_PRCTL, tid, base, ARCH_SET_FS) < 0)
	      perror_with_name (_("Couldn't write segment register fs_base"));
	  }
	if (regnum == -1 || regnum == AMD64_GSBASE_REGNUM)
	  {

	    regcache_raw_collect (regcache, AMD64_GSBASE_REGNUM, &base);
	    if (ptrace (PTRACE_ARCH_PRCTL, tid, base, ARCH_SET_GS) < 0)
	      perror_with_name (_("Couldn't write segment register gs_base"));
	  }
      }
#endif
    }
}


/* This function is called by libthread_db as part of its handling of
   a request for a thread's local storage address.  */

ps_err_e
ps_get_thread_area (struct ps_prochandle *ph,
                    lwpid_t lwpid, int idx, void **base)
{
  if (gdbarch_bfd_arch_info (target_gdbarch ())->bits_per_word == 32)
    {
      unsigned int base_addr;
      ps_err_e result;

      result = x86_linux_get_thread_area (lwpid, (void *) (long) idx,
					  &base_addr);
      if (result == PS_OK)
	{
	  /* Extend the value to 64 bits.  Here it's assumed that
	     a "long" and a "void *" are the same.  */
	  (*base) = (void *) (long) base_addr;
	}
      return result;
    }
  else
    {

      /* FIXME: ezannoni-2003-07-09 see comment above about include
	 file order.  We could be getting bogus values for these two.  */
      gdb_assert (FS < ELF_NGREG);
      gdb_assert (GS < ELF_NGREG);
      switch (idx)
	{
	case FS:
#ifdef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE
	    {
	      /* PTRACE_ARCH_PRCTL is obsolete since 2.6.25, where the
		 fs_base and gs_base fields of user_regs_struct can be
		 used directly.  */
	      unsigned long fs;
	      errno = 0;
	      fs = ptrace (PTRACE_PEEKUSER, lwpid,
			   offsetof (struct user_regs_struct, fs_base), 0);
	      if (errno == 0)
		{
		  *base = (void *) fs;
		  return PS_OK;
		}
	    }
#endif
	  if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0)
	    return PS_OK;
	  break;
	case GS:
#ifdef HAVE_STRUCT_USER_REGS_STRUCT_GS_BASE
	    {
	      unsigned long gs;
	      errno = 0;
	      gs = ptrace (PTRACE_PEEKUSER, lwpid,
			   offsetof (struct user_regs_struct, gs_base), 0);
	      if (errno == 0)
		{
		  *base = (void *) gs;
		  return PS_OK;
		}
	    }
#endif
	  if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0)
	    return PS_OK;
	  break;
	default:                   /* Should not happen.  */
	  return PS_BADADDR;
	}
    }
  return PS_ERR;               /* ptrace failed.  */
}


/* Convert a ptrace/host siginfo object, into/from the siginfo in the
   layout of the inferiors' architecture.  Returns true if any
   conversion was done; false otherwise.  If DIRECTION is 1, then copy
   from INF to PTRACE.  If DIRECTION is 0, copy from PTRACE to
   INF.  */

static int
amd64_linux_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, int direction)
{
  struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());

  /* Is the inferior 32-bit?  If so, then do fixup the siginfo
     object.  */
  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
      return amd64_linux_siginfo_fixup_common (ptrace, inf, direction,
					       FIXUP_32);
  /* No fixup for native x32 GDB.  */
  else if (gdbarch_addr_bit (gdbarch) == 32 && sizeof (void *) == 8)
      return amd64_linux_siginfo_fixup_common (ptrace, inf, direction,
					       FIXUP_X32);
  else
    return 0;
}

void
_initialize_amd64_linux_nat (void)
{
  struct target_ops *t;

  amd64_native_gregset32_reg_offset = amd64_linux_gregset32_reg_offset;
  amd64_native_gregset32_num_regs = I386_LINUX_NUM_REGS;
  amd64_native_gregset64_reg_offset = amd64_linux_gregset_reg_offset;
  amd64_native_gregset64_num_regs = AMD64_LINUX_NUM_REGS;

  gdb_assert (ARRAY_SIZE (amd64_linux_gregset32_reg_offset)
	      == amd64_native_gregset32_num_regs);

  /* Create a generic x86 GNU/Linux target.  */
  t = x86_linux_create_target ();

  /* Add our register access methods.  */
  t->to_fetch_registers = amd64_linux_fetch_inferior_registers;
  t->to_store_registers = amd64_linux_store_inferior_registers;

  /* Add the target.  */
  x86_linux_add_target (t);

  /* Add our siginfo layout converter.  */
  linux_nat_set_siginfo_fixup (t, amd64_linux_siginfo_fixup);
}
