/* GNU/Linux/x86 specific low level interface, for the in-process
   agent library for GDB.

   Copyright (C) 2010-2021 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 "server.h"
#include <sys/mman.h>
#include "tracepoint.h"
#include "linux-x86-tdesc.h"
#include "gdbsupport/x86-xstate.h"

/* GDB register numbers.  */

enum i386_gdb_regnum
{
  I386_EAX_REGNUM,		/* %eax */
  I386_ECX_REGNUM,		/* %ecx */
  I386_EDX_REGNUM,		/* %edx */
  I386_EBX_REGNUM,		/* %ebx */
  I386_ESP_REGNUM,		/* %esp */
  I386_EBP_REGNUM,		/* %ebp */
  I386_ESI_REGNUM,		/* %esi */
  I386_EDI_REGNUM,		/* %edi */
  I386_EIP_REGNUM,		/* %eip */
  I386_EFLAGS_REGNUM,		/* %eflags */
  I386_CS_REGNUM,		/* %cs */
  I386_SS_REGNUM,		/* %ss */
  I386_DS_REGNUM,		/* %ds */
  I386_ES_REGNUM,		/* %es */
  I386_FS_REGNUM,		/* %fs */
  I386_GS_REGNUM,		/* %gs */
  I386_ST0_REGNUM		/* %st(0) */
};

#define i386_num_regs 16

#define FT_CR_EAX 15
#define FT_CR_ECX 14
#define FT_CR_EDX 13
#define FT_CR_EBX 12
#define FT_CR_UESP 11
#define FT_CR_EBP 10
#define FT_CR_ESI 9
#define FT_CR_EDI 8
#define FT_CR_EIP 7
#define FT_CR_EFL 6
#define FT_CR_DS 5
#define FT_CR_ES 4
#define FT_CR_FS 3
#define FT_CR_GS 2
#define FT_CR_SS 1
#define FT_CR_CS 0

/* Mapping between the general-purpose registers in jump tracepoint
   format and GDB's register array layout.  */

static const int i386_ft_collect_regmap[] =
{
  FT_CR_EAX * 4, FT_CR_ECX * 4, FT_CR_EDX * 4, FT_CR_EBX * 4,
  FT_CR_UESP * 4, FT_CR_EBP * 4, FT_CR_ESI * 4, FT_CR_EDI * 4,
  FT_CR_EIP * 4, FT_CR_EFL * 4, FT_CR_CS * 4, FT_CR_SS * 4,
  FT_CR_DS * 4, FT_CR_ES * 4, FT_CR_FS * 4, FT_CR_GS * 4
};

void
supply_fast_tracepoint_registers (struct regcache *regcache,
				  const unsigned char *buf)
{
  int i;

  for (i = 0; i < i386_num_regs; i++)
    {
      int regval;

      if (i >= I386_CS_REGNUM && i <= I386_GS_REGNUM)
	regval = *(short *) (((char *) buf) + i386_ft_collect_regmap[i]);
      else
	regval = *(int *) (((char *) buf) + i386_ft_collect_regmap[i]);

      supply_register (regcache, i, &regval);
    }
}

ULONGEST
get_raw_reg (const unsigned char *raw_regs, int regnum)
{
  /* This should maybe be allowed to return an error code, or perhaps
     better, have the emit_reg detect this, and emit a constant zero,
     or something.  */

  if (regnum > i386_num_regs)
    return 0;
  else if (regnum >= I386_CS_REGNUM && regnum <= I386_GS_REGNUM)
    return *(short *) (raw_regs + i386_ft_collect_regmap[regnum]);
  else
    return *(int *) (raw_regs + i386_ft_collect_regmap[regnum]);
}

#ifdef HAVE_UST

#include <ust/processor.h>

/* "struct registers" is the UST object type holding the registers at
   the time of the static tracepoint marker call.  This doesn't
   contain EIP, but we know what it must have been (the marker
   address).  */

#define ST_REGENTRY(REG)			\
  {						\
    offsetof (struct registers, REG),		\
    sizeof (((struct registers *) NULL)->REG)	\
  }

static struct
{
  int offset;
  int size;
} i386_st_collect_regmap[] =
  {
    ST_REGENTRY(eax),
    ST_REGENTRY(ecx),
    ST_REGENTRY(edx),
    ST_REGENTRY(ebx),
    ST_REGENTRY(esp),
    ST_REGENTRY(ebp),
    ST_REGENTRY(esi),
    ST_REGENTRY(edi),
    { -1, 0 }, /* eip */
    ST_REGENTRY(eflags),
    ST_REGENTRY(cs),
    ST_REGENTRY(ss),
  };

#define i386_NUM_ST_COLLECT_GREGS \
  (sizeof (i386_st_collect_regmap) / sizeof (i386_st_collect_regmap[0]))

void
supply_static_tracepoint_registers (struct regcache *regcache,
				    const unsigned char *buf,
				    CORE_ADDR pc)
{
  int i;
  unsigned int newpc = pc;

  supply_register (regcache, I386_EIP_REGNUM, &newpc);

  for (i = 0; i < i386_NUM_ST_COLLECT_GREGS; i++)
    if (i386_st_collect_regmap[i].offset != -1)
      {
	switch (i386_st_collect_regmap[i].size)
	  {
	  case 4:
	    supply_register (regcache, i,
			     ((char *) buf)
			     + i386_st_collect_regmap[i].offset);
	    break;
	  case 2:
	    {
	      unsigned long reg
		= * (short *) (((char *) buf)
			       + i386_st_collect_regmap[i].offset);
	      reg &= 0xffff;
	      supply_register (regcache, i, &reg);
	    }
	    break;
	  default:
	    internal_error (__FILE__, __LINE__, "unhandled register size: %d",
			    i386_st_collect_regmap[i].size);
	  }
      }
}

#endif /* HAVE_UST */


/* This is only needed because reg-i386-linux-lib.o references it.  We
   may use it proper at some point.  */
const char *gdbserver_xmltarget;

/* Attempt to allocate memory for trampolines in the first 64 KiB of
   memory to enable smaller jump patches.  */

static void
initialize_fast_tracepoint_trampoline_buffer (void)
{
  const CORE_ADDR buffer_end = 64 * 1024;
  /* Ensure that the buffer will be at least 1 KiB in size, which is
     enough space for over 200 fast tracepoints.  */
  const int min_buffer_size = 1024;
  char buf[IPA_BUFSIZ];
  CORE_ADDR mmap_min_addr = buffer_end + 1;
  ULONGEST buffer_size;
  FILE *f = fopen ("/proc/sys/vm/mmap_min_addr", "r");

  if (!f)
    {    
      snprintf (buf, sizeof (buf), "mmap_min_addr open failed: %s",
		safe_strerror (errno));
      set_trampoline_buffer_space (0, 0, buf);
      return;
    }

  if (fgets (buf, IPA_BUFSIZ, f))
    sscanf (buf, "%llu", &mmap_min_addr);
      
  fclose (f);
      
  buffer_size = buffer_end - mmap_min_addr;

  if (buffer_size >= min_buffer_size)
    {
      if (mmap ((void *) (uintptr_t) mmap_min_addr, buffer_size,
		PROT_READ | PROT_EXEC | PROT_WRITE,
		MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,
		-1, 0)
	  != MAP_FAILED)
	set_trampoline_buffer_space (mmap_min_addr, buffer_end, NULL);
      else
	{
	  snprintf (buf, IPA_BUFSIZ, "low-64K-buffer mmap() failed: %s",
		    safe_strerror (errno));
	  set_trampoline_buffer_space (0, 0, buf);
	}
    }
  else
    {
      snprintf (buf, IPA_BUFSIZ, "mmap_min_addr is %d, must be %d or less",
		(int) mmap_min_addr, (int) buffer_end - min_buffer_size);
      set_trampoline_buffer_space (0, 0, buf);
    }
}

/* Map the tdesc index to xcr0 mask.  */
static uint64_t idx2mask[X86_TDESC_LAST] = {
  X86_XSTATE_X87_MASK,
  X86_XSTATE_SSE_MASK,
  X86_XSTATE_AVX_MASK,
  X86_XSTATE_MPX_MASK,
  X86_XSTATE_AVX_MPX_MASK,
  X86_XSTATE_AVX_AVX512_MASK,
  X86_XSTATE_AVX_MPX_AVX512_PKU_MASK,
};

/* Return target_desc to use for IPA, given the tdesc index passed by
   gdbserver.  */

const struct target_desc *
get_ipa_tdesc (int idx)
{
  if (idx >= X86_TDESC_LAST)
    {
      internal_error (__FILE__, __LINE__,
		      "unknown ipa tdesc index: %d", idx);
    }
  return i386_linux_read_description (idx2mask[idx]);
}

/* Allocate buffer for the jump pads.  On i386, we can reach an arbitrary
   address with a jump instruction, so just allocate normally.  */

void *
alloc_jump_pad_buffer (size_t size)
{
  void *res = mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,
		    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

  if (res == MAP_FAILED)
    return NULL;

  return res;
}

void
initialize_low_tracepoint (void)
{
  initialize_fast_tracepoint_trampoline_buffer ();
  for (auto i = 0; i < X86_TDESC_LAST; i++)
    i386_linux_read_description (idx2mask[i]);
}
