/* Copyright (C) 2009-2022 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 "amd64-tdep.h"
#include "gdbsupport/x86-xstate.h"
#include "gdbtypes.h"
#include "gdbcore.h"
#include "regcache.h"
#include "windows-tdep.h"
#include "frame.h"
#include "objfiles.h"
#include "frame-unwind.h"
#include "coff/internal.h"
#include "coff/i386.h"
#include "coff/pe.h"
#include "libcoff.h"
#include "value.h"
#include <algorithm>

/* The registers used to pass integer arguments during a function call.  */
static int amd64_windows_dummy_call_integer_regs[] =
{
  AMD64_RCX_REGNUM,          /* %rcx */
  AMD64_RDX_REGNUM,          /* %rdx */
  AMD64_R8_REGNUM,           /* %r8 */
  AMD64_R9_REGNUM            /* %r9 */
};

/* This vector maps GDB's idea of a register's number into an offset into
   the Windows API CONTEXT structure.  */
static int amd64_windows_gregset_reg_offset[] =
{
  120, /* Rax */
  144, /* Rbx */
  128, /* Rcx */
  136, /* Rdx */
  168, /* Rsi */
  176, /* Rdi */
  160, /* Rbp */
  152, /* Rsp */
  184, /* R8 */
  192, /* R9 */
  200, /* R10 */
  208, /* R11 */
  216, /* R12 */
  224, /* R13 */
  232, /* R14 */
  240, /* R15 */
  248, /* Rip */
  68,  /* EFlags */
  56,  /* SegCs */
  66,  /* SegSs */
  58,  /* SegDs */
  60,  /* SegEs */
  62,  /* SegFs */
  64,  /* SegGs */
  288, /* FloatSave.FloatRegisters[0] */
  304, /* FloatSave.FloatRegisters[1] */
  320, /* FloatSave.FloatRegisters[2] */
  336, /* FloatSave.FloatRegisters[3] */
  352, /* FloatSave.FloatRegisters[4] */
  368, /* FloatSave.FloatRegisters[5] */
  384, /* FloatSave.FloatRegisters[6] */
  400, /* FloatSave.FloatRegisters[7] */
  256, /* FloatSave.ControlWord */
  258, /* FloatSave.StatusWord */
  260, /* FloatSave.TagWord */
  268, /* FloatSave.ErrorSelector */
  264, /* FloatSave.ErrorOffset */
  276, /* FloatSave.DataSelector */
  272, /* FloatSave.DataOffset */
  268, /* FloatSave.ErrorSelector */
  416, /* Xmm0 */
  432, /* Xmm1 */
  448, /* Xmm2 */
  464, /* Xmm3 */
  480, /* Xmm4 */
  496, /* Xmm5 */
  512, /* Xmm6 */
  528, /* Xmm7 */
  544, /* Xmm8 */
  560, /* Xmm9 */
  576, /* Xmm10 */
  592, /* Xmm11 */
  608, /* Xmm12 */
  624, /* Xmm13 */
  640, /* Xmm14 */
  656, /* Xmm15 */
  280, /* FloatSave.MxCsr */
};

#define AMD64_WINDOWS_SIZEOF_GREGSET 1232

/* Return nonzero if an argument of type TYPE should be passed
   via one of the integer registers.  */

static int
amd64_windows_passed_by_integer_register (struct type *type)
{
  switch (type->code ())
    {
      case TYPE_CODE_INT:
      case TYPE_CODE_ENUM:
      case TYPE_CODE_BOOL:
      case TYPE_CODE_RANGE:
      case TYPE_CODE_CHAR:
      case TYPE_CODE_PTR:
      case TYPE_CODE_REF:
      case TYPE_CODE_RVALUE_REF:
      case TYPE_CODE_STRUCT:
      case TYPE_CODE_UNION:
      case TYPE_CODE_COMPLEX:
	return (type->length () == 1
		|| type->length () == 2
		|| type->length () == 4
		|| type->length () == 8);

      default:
	return 0;
    }
}

/* Return nonzero if an argument of type TYPE should be passed
   via one of the XMM registers.  */

static int
amd64_windows_passed_by_xmm_register (struct type *type)
{
  return ((type->code () == TYPE_CODE_FLT
	   || type->code () == TYPE_CODE_DECFLOAT)
	  && (type->length () == 4 || type->length () == 8));
}

/* Return non-zero iff an argument of the given TYPE should be passed
   by pointer.  */

static int
amd64_windows_passed_by_pointer (struct type *type)
{
  if (amd64_windows_passed_by_integer_register (type))
    return 0;

  if (amd64_windows_passed_by_xmm_register (type))
    return 0;

  return 1;
}

/* For each argument that should be passed by pointer, reserve some
   stack space, store a copy of the argument on the stack, and replace
   the argument by its address.  Return the new Stack Pointer value.

   NARGS is the number of arguments. ARGS is the array containing
   the value of each argument.  SP is value of the Stack Pointer.  */

static CORE_ADDR
amd64_windows_adjust_args_passed_by_pointer (struct value **args,
					     int nargs, CORE_ADDR sp)
{
  int i;

  for (i = 0; i < nargs; i++)
    if (amd64_windows_passed_by_pointer (value_type (args[i])))
      {
	struct type *type = value_type (args[i]);
	const gdb_byte *valbuf = value_contents (args[i]).data ();
	const int len = type->length ();

	/* Store a copy of that argument on the stack, aligned to
	   a 16 bytes boundary, and then use the copy's address as
	   the argument.  */

	sp -= len;
	sp &= ~0xf;
	write_memory (sp, valbuf, len);

	args[i]
	  = value_addr (value_from_contents_and_address (type, valbuf, sp));
      }

  return sp;
}

/* Store the value of ARG in register REGNO (right-justified).
   REGCACHE is the register cache.  */

static void
amd64_windows_store_arg_in_reg (struct regcache *regcache,
				struct value *arg, int regno)
{
  struct type *type = value_type (arg);
  const gdb_byte *valbuf = value_contents (arg).data ();
  gdb_byte buf[8];

  gdb_assert (type->length () <= 8);
  memset (buf, 0, sizeof buf);
  memcpy (buf, valbuf, std::min (type->length (), (ULONGEST) 8));
  regcache->cooked_write (regno, buf);
}

/* Push the arguments for an inferior function call, and return
   the updated value of the SP (Stack Pointer).

   All arguments are identical to the arguments used in
   amd64_windows_push_dummy_call.  */

static CORE_ADDR
amd64_windows_push_arguments (struct regcache *regcache, int nargs,
			      struct value **args, CORE_ADDR sp,
			      function_call_return_method return_method)
{
  int reg_idx = 0;
  int i;
  struct value **stack_args = XALLOCAVEC (struct value *, nargs);
  int num_stack_args = 0;
  int num_elements = 0;
  int element = 0;

  /* First, handle the arguments passed by pointer.

     These arguments are replaced by pointers to a copy we are making
     in inferior memory.  So use a copy of the ARGS table, to avoid
     modifying the original one.  */
  {
    struct value **args1 = XALLOCAVEC (struct value *, nargs);

    memcpy (args1, args, nargs * sizeof (struct value *));
    sp = amd64_windows_adjust_args_passed_by_pointer (args1, nargs, sp);
    args = args1;
  }

  /* Reserve a register for the "hidden" argument.  */
  if (return_method == return_method_struct)
    reg_idx++;

  for (i = 0; i < nargs; i++)
    {
      struct type *type = value_type (args[i]);
      int len = type->length ();
      int on_stack_p = 1;

      if (reg_idx < ARRAY_SIZE (amd64_windows_dummy_call_integer_regs))
	{
	  if (amd64_windows_passed_by_integer_register (type))
	    {
	      amd64_windows_store_arg_in_reg
		(regcache, args[i],
		 amd64_windows_dummy_call_integer_regs[reg_idx]);
	      on_stack_p = 0;
	      reg_idx++;
	    }
	  else if (amd64_windows_passed_by_xmm_register (type))
	    {
	      amd64_windows_store_arg_in_reg
		(regcache, args[i], AMD64_XMM0_REGNUM + reg_idx);
	      /* In case of varargs, these parameters must also be
		 passed via the integer registers.  */
	      amd64_windows_store_arg_in_reg
		(regcache, args[i],
		 amd64_windows_dummy_call_integer_regs[reg_idx]);
	      on_stack_p = 0;
	      reg_idx++;
	    }
	}

      if (on_stack_p)
	{
	  num_elements += ((len + 7) / 8);
	  stack_args[num_stack_args++] = args[i];
	}
    }

  /* Allocate space for the arguments on the stack, keeping it
     aligned on a 16 byte boundary.  */
  sp -= num_elements * 8;
  sp &= ~0xf;

  /* Write out the arguments to the stack.  */
  for (i = 0; i < num_stack_args; i++)
    {
      struct type *type = value_type (stack_args[i]);
      const gdb_byte *valbuf = value_contents (stack_args[i]).data ();

      write_memory (sp + element * 8, valbuf, type->length ());
      element += ((type->length () + 7) / 8);
    }

  return sp;
}

/* Implement the "push_dummy_call" gdbarch method.  */

static CORE_ADDR
amd64_windows_push_dummy_call
  (struct gdbarch *gdbarch, struct value *function,
   struct regcache *regcache, CORE_ADDR bp_addr,
   int nargs, struct value **args, CORE_ADDR sp,
   function_call_return_method return_method, CORE_ADDR struct_addr)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  gdb_byte buf[8];

  /* Pass arguments.  */
  sp = amd64_windows_push_arguments (regcache, nargs, args, sp,
				     return_method);

  /* Pass "hidden" argument".  */
  if (return_method == return_method_struct)
    {
      /* The "hidden" argument is passed throught the first argument
	 register.  */
      const int arg_regnum = amd64_windows_dummy_call_integer_regs[0];

      store_unsigned_integer (buf, 8, byte_order, struct_addr);
      regcache->cooked_write (arg_regnum, buf);
    }

  /* Reserve some memory on the stack for the integer-parameter
     registers, as required by the ABI.  */
  sp -= ARRAY_SIZE (amd64_windows_dummy_call_integer_regs) * 8;

  /* Store return address.  */
  sp -= 8;
  store_unsigned_integer (buf, 8, byte_order, bp_addr);
  write_memory (sp, buf, 8);

  /* Update the stack pointer...  */
  store_unsigned_integer (buf, 8, byte_order, sp);
  regcache->cooked_write (AMD64_RSP_REGNUM, buf);

  /* ...and fake a frame pointer.  */
  regcache->cooked_write (AMD64_RBP_REGNUM, buf);

  return sp + 16;
}

/* Implement the "return_value" gdbarch method for amd64-windows.  */

static enum return_value_convention
amd64_windows_return_value (struct gdbarch *gdbarch, struct value *function,
			    struct type *type, struct regcache *regcache,
			    gdb_byte *readbuf, const gdb_byte *writebuf)
{
  int len = type->length ();
  int regnum = -1;

  /* See if our value is returned through a register.  If it is, then
     store the associated register number in REGNUM.  */
  switch (type->code ())
    {
      case TYPE_CODE_FLT:
	/* floats, and doubles are returned via XMM0.  */
	if (len == 4 || len == 8)
	  regnum = AMD64_XMM0_REGNUM;
	break;
      case TYPE_CODE_ARRAY:
	/* __m128, __m128i and __m128d are returned via XMM0.  */
	if (type->is_vector () && len == 16)
	  {
	    enum type_code code = type->target_type ()->code ();
	    if (code == TYPE_CODE_INT || code == TYPE_CODE_FLT)
	      {
		regnum = AMD64_XMM0_REGNUM;
		break;
	      }
	  }
	/* fall through */
      default:
	/* All other values that are 1, 2, 4 or 8 bytes long are returned
	   via RAX.  */
	if (len == 1 || len == 2 || len == 4 || len == 8)
	  regnum = AMD64_RAX_REGNUM;
	else if (len == 16 && type->code () == TYPE_CODE_INT)
	  regnum = AMD64_XMM0_REGNUM;
	break;
    }

  if (regnum < 0)
    {
      /* RAX contains the address where the return value has been stored.  */
      if (readbuf)
	{
	  ULONGEST addr;

	  regcache_raw_read_unsigned (regcache, AMD64_RAX_REGNUM, &addr);
	  read_memory (addr, readbuf, type->length ());
	}
      return RETURN_VALUE_ABI_RETURNS_ADDRESS;
    }
  else
    {
      /* Extract the return value from the register where it was stored.  */
      if (readbuf)
	regcache->raw_read_part (regnum, 0, len, readbuf);
      if (writebuf)
	regcache->raw_write_part (regnum, 0, len, writebuf);
      return RETURN_VALUE_REGISTER_CONVENTION;
    }
}

/* Check that the code pointed to by PC corresponds to a call to
   __main, skip it if so.  Return PC otherwise.  */

static CORE_ADDR
amd64_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  gdb_byte op;

  target_read_memory (pc, &op, 1);
  if (op == 0xe8)
    {
      gdb_byte buf[4];

      if (target_read_memory (pc + 1, buf, sizeof buf) == 0)
	{
	  struct bound_minimal_symbol s;
	  CORE_ADDR call_dest;

	  call_dest = pc + 5 + extract_signed_integer (buf, 4, byte_order);
	  s = lookup_minimal_symbol_by_pc (call_dest);
	  if (s.minsym != NULL
	      && s.minsym->linkage_name () != NULL
	      && strcmp (s.minsym->linkage_name (), "__main") == 0)
	    pc += 5;
	}
    }

  return pc;
}

struct amd64_windows_frame_cache
{
  /* ImageBase for the module.  */
  CORE_ADDR image_base;

  /* Function start and end rva.  */
  CORE_ADDR start_rva;
  CORE_ADDR end_rva;

  /* Next instruction to be executed.  */
  CORE_ADDR pc;

  /* Current sp.  */
  CORE_ADDR sp;

  /* Address of saved integer and xmm registers.  */
  CORE_ADDR prev_reg_addr[16];
  CORE_ADDR prev_xmm_addr[16];

  /* These two next fields are set only for machine info frames.  */

  /* Likewise for RIP.  */
  CORE_ADDR prev_rip_addr;

  /* Likewise for RSP.  */
  CORE_ADDR prev_rsp_addr;

  /* Address of the previous frame.  */
  CORE_ADDR prev_sp;
};

/* Convert a Windows register number to gdb.  */
static const enum amd64_regnum amd64_windows_w2gdb_regnum[] =
{
  AMD64_RAX_REGNUM,
  AMD64_RCX_REGNUM,
  AMD64_RDX_REGNUM,
  AMD64_RBX_REGNUM,
  AMD64_RSP_REGNUM,
  AMD64_RBP_REGNUM,
  AMD64_RSI_REGNUM,
  AMD64_RDI_REGNUM,
  AMD64_R8_REGNUM,
  AMD64_R9_REGNUM,
  AMD64_R10_REGNUM,
  AMD64_R11_REGNUM,
  AMD64_R12_REGNUM,
  AMD64_R13_REGNUM,
  AMD64_R14_REGNUM,
  AMD64_R15_REGNUM
};

/* Return TRUE iff PC is the range of the function corresponding to
   CACHE.  */

static int
pc_in_range (CORE_ADDR pc, const struct amd64_windows_frame_cache *cache)
{
  return (pc >= cache->image_base + cache->start_rva
	  && pc < cache->image_base + cache->end_rva);
}

/* Try to recognize and decode an epilogue sequence.

   Return -1 if we fail to read the instructions for any reason.
   Return 1 if an epilogue sequence was recognized, 0 otherwise.  */

static int
amd64_windows_frame_decode_epilogue (frame_info_ptr this_frame,
				     struct amd64_windows_frame_cache *cache)
{
  /* According to MSDN an epilogue "must consist of either an add RSP,constant
     or lea RSP,constant[FPReg], followed by a series of zero or more 8-byte
     register pops and a return or a jmp".

     Furthermore, according to RtlVirtualUnwind, the complete list of
     epilog marker is:
     - ret                      [c3]
     - ret n                    [c2 imm16]
     - rep ret                  [f3 c3]
     - jmp imm8 | imm32         [eb rel8] or [e9 rel32]
     - jmp qword ptr imm32                 - not handled
     - rex.w jmp reg            [4X ff eY]
  */

  CORE_ADDR pc = cache->pc;
  CORE_ADDR cur_sp = cache->sp;
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  gdb_byte op;
  gdb_byte rex;

  /* We don't care about the instruction deallocating the frame:
     if it hasn't been executed, the pc is still in the body,
     if it has been executed, the following epilog decoding will work.  */

  /* First decode:
     -  pop reg                 [41 58-5f] or [58-5f].  */

  while (1)
    {
      /* Read opcode. */
      if (target_read_memory (pc, &op, 1) != 0)
	return -1;

      if (op >= 0x40 && op <= 0x4f)
	{
	  /* REX prefix.  */
	  rex = op;

	  /* Read opcode. */
	  if (target_read_memory (pc + 1, &op, 1) != 0)
	    return -1;
	}
      else
	rex = 0;

      if (op >= 0x58 && op <= 0x5f)
	{
	  /* pop reg  */
	  gdb_byte reg = (op & 0x0f) | ((rex & 1) << 3);

	  cache->prev_reg_addr[amd64_windows_w2gdb_regnum[reg]] = cur_sp;
	  cur_sp += 8;
	  pc += rex ? 2 : 1;
	}
      else
	break;

      /* Allow the user to break this loop.  This shouldn't happen as the
	 number of consecutive pop should be small.  */
      QUIT;
    }

  /* Then decode the marker.  */

  /* Read opcode.  */
  if (target_read_memory (pc, &op, 1) != 0)
    return -1;

  switch (op)
    {
    case 0xc3:
      /* Ret.  */
      cache->prev_rip_addr = cur_sp;
      cache->prev_sp = cur_sp + 8;
      return 1;

    case 0xeb:
      {
	/* jmp rel8  */
	gdb_byte rel8;
	CORE_ADDR npc;

	if (target_read_memory (pc + 1, &rel8, 1) != 0)
	  return -1;
	npc = pc + 2 + (signed char) rel8;

	/* If the jump is within the function, then this is not a marker,
	   otherwise this is a tail-call.  */
	return !pc_in_range (npc, cache);
      }

    case 0xec:
      {
	/* jmp rel32  */
	gdb_byte rel32[4];
	CORE_ADDR npc;

	if (target_read_memory (pc + 1, rel32, 4) != 0)
	  return -1;
	npc = pc + 5 + extract_signed_integer (rel32, 4, byte_order);

	/* If the jump is within the function, then this is not a marker,
	   otherwise this is a tail-call.  */
	return !pc_in_range (npc, cache);
      }

    case 0xc2:
      {
	/* ret n  */
	gdb_byte imm16[2];

	if (target_read_memory (pc + 1, imm16, 2) != 0)
	  return -1;
	cache->prev_rip_addr = cur_sp;
	cache->prev_sp = cur_sp
	  + extract_unsigned_integer (imm16, 4, byte_order);
	return 1;
      }

    case 0xf3:
      {
	/* rep; ret  */
	gdb_byte op1;

	if (target_read_memory (pc + 2, &op1, 1) != 0)
	  return -1;
	if (op1 != 0xc3)
	  return 0;

	cache->prev_rip_addr = cur_sp;
	cache->prev_sp = cur_sp + 8;
	return 1;
      }

    case 0x40:
    case 0x41:
    case 0x42:
    case 0x43:
    case 0x44:
    case 0x45:
    case 0x46:
    case 0x47:
    case 0x48:
    case 0x49:
    case 0x4a:
    case 0x4b:
    case 0x4c:
    case 0x4d:
    case 0x4e:
    case 0x4f:
      /* Got a REX prefix, read next byte.  */
      rex = op;
      if (target_read_memory (pc + 1, &op, 1) != 0)
	return -1;

      if (op == 0xff)
	{
	  /* rex jmp reg  */
	  gdb_byte op1;

	  if (target_read_memory (pc + 2, &op1, 1) != 0)
	    return -1;
	  return (op1 & 0xf8) == 0xe0;
	}
      else
	return 0;

    default:
      /* Not REX, so unknown.  */
      return 0;
    }
}

/* Decode and execute unwind insns at UNWIND_INFO.  */

static void
amd64_windows_frame_decode_insns (frame_info_ptr this_frame,
				  struct amd64_windows_frame_cache *cache,
				  CORE_ADDR unwind_info)
{
  CORE_ADDR save_addr = 0;
  CORE_ADDR cur_sp = cache->sp;
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int first = 1;

  /* There are at least 3 possibilities to share an unwind info entry:
     1. Two different runtime_function entries (in .pdata) can point to the
	same unwind info entry.  There is no such indication while unwinding,
	so we don't really care about that case.  We suppose this scheme is
	used to save memory when the unwind entries are exactly the same.
     2. Chained unwind_info entries, with no unwind codes (no prologue).
	There is a major difference with the previous case: the pc range for
	the function is different (in case 1, the pc range comes from the
	runtime_function entry; in case 2, the pc range for the chained entry
	comes from the first unwind entry).  Case 1 cannot be used instead as
	the pc is not in the prologue.  This case is officially documented.
	(There might be unwind code in the first unwind entry to handle
	additional unwinding).  GCC (at least until gcc 5.0) doesn't chain
	entries.
     3. Undocumented unwind info redirection.  Hard to know the exact purpose,
	so it is considered as a memory optimization of case 2.
  */

  if (unwind_info & 1)
    {
      /* Unofficially documented unwind info redirection, when UNWIND_INFO
	 address is odd (http://www.codemachine.com/article_x64deepdive.html).
      */
      struct external_pex64_runtime_function d;

      if (target_read_memory (cache->image_base + (unwind_info & ~1),
			      (gdb_byte *) &d, sizeof (d)) != 0)
	return;

      cache->start_rva
	= extract_unsigned_integer (d.rva_BeginAddress, 4, byte_order);
      cache->end_rva
	= extract_unsigned_integer (d.rva_EndAddress, 4, byte_order);
      unwind_info
	= extract_unsigned_integer (d.rva_UnwindData, 4, byte_order);
    }

  while (1)
    {
      struct external_pex64_unwind_info ex_ui;
      /* There are at most 256 16-bit unwind insns.  */
      gdb_byte insns[2 * 256];
      gdb_byte *p;
      gdb_byte *end_insns;
      unsigned char codes_count;
      unsigned char frame_reg;
      CORE_ADDR start;

      /* Read and decode header.  */
      if (target_read_memory (cache->image_base + unwind_info,
			      (gdb_byte *) &ex_ui, sizeof (ex_ui)) != 0)
	return;

      frame_debug_printf ("%s: ver: %02x, plgsz: %02x, cnt: %02x, frame: %02x",
			  paddress (gdbarch, unwind_info),
			  ex_ui.Version_Flags, ex_ui.SizeOfPrologue,
			  ex_ui.CountOfCodes, ex_ui.FrameRegisterOffset);

      /* Check version.  */
      if (PEX64_UWI_VERSION (ex_ui.Version_Flags) != 1
	  && PEX64_UWI_VERSION (ex_ui.Version_Flags) != 2)
	return;

      start = cache->image_base + cache->start_rva;
      if (first
	  && !(cache->pc >= start && cache->pc < start + ex_ui.SizeOfPrologue))
	{
	  /* We want to detect if the PC points to an epilogue.  This needs
	     to be checked only once, and an epilogue can be anywhere but in
	     the prologue.  If so, the epilogue detection+decoding function is
	     sufficient.  Otherwise, the unwinder will consider that the PC
	     is in the body of the function and will need to decode unwind
	     info.  */
	  if (amd64_windows_frame_decode_epilogue (this_frame, cache) == 1)
	    return;

	  /* Not in an epilog.  Clear possible side effects.  */
	  memset (cache->prev_reg_addr, 0, sizeof (cache->prev_reg_addr));
	}

      codes_count = ex_ui.CountOfCodes;
      frame_reg = PEX64_UWI_FRAMEREG (ex_ui.FrameRegisterOffset);

      if (frame_reg != 0)
	{
	  /* According to msdn:
	     If an FP reg is used, then any unwind code taking an offset must
	     only be used after the FP reg is established in the prolog.  */
	  gdb_byte buf[8];
	  int frreg = amd64_windows_w2gdb_regnum[frame_reg];

	  get_frame_register (this_frame, frreg, buf);
	  save_addr = extract_unsigned_integer (buf, 8, byte_order);

	  frame_debug_printf ("   frame_reg=%s, val=%s",
			      gdbarch_register_name (gdbarch, frreg),
			      paddress (gdbarch, save_addr));
	}

      /* Read opcodes.  */
      if (codes_count != 0
	  && target_read_memory (cache->image_base + unwind_info
				 + sizeof (ex_ui),
				 insns, codes_count * 2) != 0)
	return;

      end_insns = &insns[codes_count * 2];
      p = insns;

      /* Skip opcodes 6 of version 2.  This opcode is not documented.  */
      if (PEX64_UWI_VERSION (ex_ui.Version_Flags) == 2)
	{
	  for (; p < end_insns; p += 2)
	    if (PEX64_UNWCODE_CODE (p[1]) != 6)
	      break;
	}

      for (; p < end_insns; p += 2)
	{
	  int reg;

	  /* Virtually execute the operation if the pc is after the
	     corresponding instruction (that does matter in case of break
	     within the prologue).  Note that for chained info (!first), the
	     prologue has been fully executed.  */
	  if (cache->pc >= start + p[0] || cache->pc < start)
	    {
	      frame_debug_printf ("   op #%u: off=0x%02x, insn=0x%02x",
				  (unsigned) (p - insns), p[0], p[1]);

	      /* If there is no frame registers defined, the current value of
		 rsp is used instead.  */
	      if (frame_reg == 0)
		save_addr = cur_sp;

	      reg = -1;

	      switch (PEX64_UNWCODE_CODE (p[1]))
		{
		case UWOP_PUSH_NONVOL:
		  /* Push pre-decrements RSP.  */
		  reg = amd64_windows_w2gdb_regnum[PEX64_UNWCODE_INFO (p[1])];
		  cache->prev_reg_addr[reg] = cur_sp;
		  cur_sp += 8;
		  break;
		case UWOP_ALLOC_LARGE:
		  if (PEX64_UNWCODE_INFO (p[1]) == 0)
		    cur_sp +=
		      8 * extract_unsigned_integer (p + 2, 2, byte_order);
		  else if (PEX64_UNWCODE_INFO (p[1]) == 1)
		    cur_sp += extract_unsigned_integer (p + 2, 4, byte_order);
		  else
		    return;
		  break;
		case UWOP_ALLOC_SMALL:
		  cur_sp += 8 + 8 * PEX64_UNWCODE_INFO (p[1]);
		  break;
		case UWOP_SET_FPREG:
		  cur_sp = save_addr
		    - PEX64_UWI_FRAMEOFF (ex_ui.FrameRegisterOffset) * 16;
		  break;
		case UWOP_SAVE_NONVOL:
		  reg = amd64_windows_w2gdb_regnum[PEX64_UNWCODE_INFO (p[1])];
		  cache->prev_reg_addr[reg] = save_addr
		    + 8 * extract_unsigned_integer (p + 2, 2, byte_order);
		  break;
		case UWOP_SAVE_NONVOL_FAR:
		  reg = amd64_windows_w2gdb_regnum[PEX64_UNWCODE_INFO (p[1])];
		  cache->prev_reg_addr[reg] = save_addr
		    + 8 * extract_unsigned_integer (p + 2, 4, byte_order);
		  break;
		case UWOP_SAVE_XMM128:
		  cache->prev_xmm_addr[PEX64_UNWCODE_INFO (p[1])] =
		    save_addr
		    - 16 * extract_unsigned_integer (p + 2, 2, byte_order);
		  break;
		case UWOP_SAVE_XMM128_FAR:
		  cache->prev_xmm_addr[PEX64_UNWCODE_INFO (p[1])] =
		    save_addr
		    - 16 * extract_unsigned_integer (p + 2, 4, byte_order);
		  break;
		case UWOP_PUSH_MACHFRAME:
		  if (PEX64_UNWCODE_INFO (p[1]) == 0)
		    {
		      cache->prev_rip_addr = cur_sp + 0;
		      cache->prev_rsp_addr = cur_sp + 24;
		      cur_sp += 40;
		    }
		  else if (PEX64_UNWCODE_INFO (p[1]) == 1)
		    {
		      cache->prev_rip_addr = cur_sp + 8;
		      cache->prev_rsp_addr = cur_sp + 32;
		      cur_sp += 48;
		    }
		  else
		    return;
		  break;
		default:
		  return;
		}

	      /* Display address where the register was saved.  */
	      if (reg >= 0)
		frame_debug_printf ("     [reg %s at %s]",
				    gdbarch_register_name (gdbarch, reg),
				    paddress (gdbarch,
					      cache->prev_reg_addr[reg]));
	    }

	  /* Adjust with the length of the opcode.  */
	  switch (PEX64_UNWCODE_CODE (p[1]))
	    {
	    case UWOP_PUSH_NONVOL:
	    case UWOP_ALLOC_SMALL:
	    case UWOP_SET_FPREG:
	    case UWOP_PUSH_MACHFRAME:
	      break;
	    case UWOP_ALLOC_LARGE:
	      if (PEX64_UNWCODE_INFO (p[1]) == 0)
		p += 2;
	      else if (PEX64_UNWCODE_INFO (p[1]) == 1)
		p += 4;
	      else
		return;
	      break;
	    case UWOP_SAVE_NONVOL:
	    case UWOP_SAVE_XMM128:
	      p += 2;
	      break;
	    case UWOP_SAVE_NONVOL_FAR:
	    case UWOP_SAVE_XMM128_FAR:
	      p += 4;
	      break;
	    default:
	      return;
	    }
	}
      if (PEX64_UWI_FLAGS (ex_ui.Version_Flags) != UNW_FLAG_CHAININFO)
	{
	  /* End of unwind info.  */
	  break;
	}
      else
	{
	  /* Read the chained unwind info.  */
	  struct external_pex64_runtime_function d;
	  CORE_ADDR chain_vma;

	  /* Not anymore the first entry.  */
	  first = 0;

	  /* Stay aligned on word boundary.  */
	  chain_vma = cache->image_base + unwind_info
	    + sizeof (ex_ui) + ((codes_count + 1) & ~1) * 2;

	  if (target_read_memory (chain_vma, (gdb_byte *) &d, sizeof (d)) != 0)
	    return;

	  /* Decode begin/end.  This may be different from .pdata index, as
	     an unwind info may be shared by several functions (in particular
	     if many functions have the same prolog and handler.  */
	  cache->start_rva =
	    extract_unsigned_integer (d.rva_BeginAddress, 4, byte_order);
	  cache->end_rva =
	    extract_unsigned_integer (d.rva_EndAddress, 4, byte_order);
	  unwind_info =
	    extract_unsigned_integer (d.rva_UnwindData, 4, byte_order);

	  frame_debug_printf ("next in chain: unwind_data=%s, start_rva=%s, "
			      "end_rva=%s",
			      paddress (gdbarch, unwind_info),
			      paddress (gdbarch, cache->start_rva),
			      paddress (gdbarch, cache->end_rva));
	}

      /* Allow the user to break this loop.  */
      QUIT;
    }
  /* PC is saved by the call.  */
  if (cache->prev_rip_addr == 0)
    cache->prev_rip_addr = cur_sp;
  cache->prev_sp = cur_sp + 8;

  frame_debug_printf ("   prev_sp: %s, prev_pc @%s",
		      paddress (gdbarch, cache->prev_sp),
		      paddress (gdbarch, cache->prev_rip_addr));
}

/* Find SEH unwind info for PC, returning 0 on success.

   UNWIND_INFO is set to the rva of unwind info address, IMAGE_BASE
   to the base address of the corresponding image, and START_RVA
   to the rva of the function containing PC.  */

static int
amd64_windows_find_unwind_info (struct gdbarch *gdbarch, CORE_ADDR pc,
				CORE_ADDR *unwind_info,
				CORE_ADDR *image_base,
				CORE_ADDR *start_rva,
				CORE_ADDR *end_rva)
{
  struct obj_section *sec;
  pe_data_type *pe;
  IMAGE_DATA_DIRECTORY *dir;
  struct objfile *objfile;
  unsigned long lo, hi;
  CORE_ADDR base;
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  /* Get the corresponding exception directory.  */
  sec = find_pc_section (pc);
  if (sec == NULL)
    return -1;
  objfile = sec->objfile;
  pe = pe_data (sec->objfile->obfd);
  dir = &pe->pe_opthdr.DataDirectory[PE_EXCEPTION_TABLE];

  base = pe->pe_opthdr.ImageBase + objfile->text_section_offset ();
  *image_base = base;

  /* Find the entry.

     Note: This does not handle dynamically added entries (for JIT
     engines).  For this, we would need to ask the kernel directly,
     which means getting some info from the native layer.  For the
     rest of the code, however, it's probably faster to search
     the entry ourselves.  */
  lo = 0;
  hi = dir->Size / sizeof (struct external_pex64_runtime_function);
  *unwind_info = 0;
  while (lo <= hi)
    {
      unsigned long mid = lo + (hi - lo) / 2;
      struct external_pex64_runtime_function d;
      CORE_ADDR sa, ea;

      if (target_read_memory (base + dir->VirtualAddress + mid * sizeof (d),
			      (gdb_byte *) &d, sizeof (d)) != 0)
	return -1;

      sa = extract_unsigned_integer (d.rva_BeginAddress, 4, byte_order);
      ea = extract_unsigned_integer (d.rva_EndAddress, 4, byte_order);
      if (pc < base + sa)
	hi = mid - 1;
      else if (pc >= base + ea)
	lo = mid + 1;
      else if (pc >= base + sa && pc < base + ea)
	{
	  /* Got it.  */
	  *start_rva = sa;
	  *end_rva = ea;
	  *unwind_info =
	    extract_unsigned_integer (d.rva_UnwindData, 4, byte_order);
	  break;
	}
      else
	break;
    }

  frame_debug_printf ("image_base=%s, unwind_data=%s",
		      paddress (gdbarch, base),
		      paddress (gdbarch, *unwind_info));

  return 0;
}

/* Fill THIS_CACHE using the native amd64-windows unwinding data
   for THIS_FRAME.  */

static struct amd64_windows_frame_cache *
amd64_windows_frame_cache (frame_info_ptr this_frame, void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct amd64_windows_frame_cache *cache;
  gdb_byte buf[8];
  CORE_ADDR pc;
  CORE_ADDR unwind_info = 0;

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

  cache = FRAME_OBSTACK_ZALLOC (struct amd64_windows_frame_cache);
  *this_cache = cache;

  /* Get current PC and SP.  */
  pc = get_frame_pc (this_frame);
  get_frame_register (this_frame, AMD64_RSP_REGNUM, buf);
  cache->sp = extract_unsigned_integer (buf, 8, byte_order);
  cache->pc = pc;

  if (amd64_windows_find_unwind_info (gdbarch, pc, &unwind_info,
				      &cache->image_base,
				      &cache->start_rva,
				      &cache->end_rva))
    return cache;

  if (unwind_info == 0)
    {
      /* Assume a leaf function.  */
      cache->prev_sp = cache->sp + 8;
      cache->prev_rip_addr = cache->sp;
    }
  else
    {
      /* Decode unwind insns to compute saved addresses.  */
      amd64_windows_frame_decode_insns (this_frame, cache, unwind_info);
    }
  return cache;
}

/* Implement the "prev_register" method of struct frame_unwind
   using the standard Windows x64 SEH info.  */

static struct value *
amd64_windows_frame_prev_register (frame_info_ptr this_frame,
				   void **this_cache, int regnum)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct amd64_windows_frame_cache *cache =
    amd64_windows_frame_cache (this_frame, this_cache);
  CORE_ADDR prev;

  frame_debug_printf ("%s for sp=%s",
		      gdbarch_register_name (gdbarch, regnum),
		      paddress (gdbarch, cache->prev_sp));

  if (regnum >= AMD64_XMM0_REGNUM && regnum <= AMD64_XMM0_REGNUM + 15)
      prev = cache->prev_xmm_addr[regnum - AMD64_XMM0_REGNUM];
  else if (regnum == AMD64_RSP_REGNUM)
    {
      prev = cache->prev_rsp_addr;
      if (prev == 0)
	return frame_unwind_got_constant (this_frame, regnum, cache->prev_sp);
    }
  else if (regnum >= AMD64_RAX_REGNUM && regnum <= AMD64_R15_REGNUM)
    prev = cache->prev_reg_addr[regnum - AMD64_RAX_REGNUM];
  else if (regnum == AMD64_RIP_REGNUM)
    prev = cache->prev_rip_addr;
  else
    prev = 0;

  if (prev != 0)
    frame_debug_printf ("  -> at %s", paddress (gdbarch, prev));

  if (prev)
    {
      /* Register was saved.  */
      return frame_unwind_got_memory (this_frame, regnum, prev);
    }
  else
    {
      /* Register is either volatile or not modified.  */
      return frame_unwind_got_register (this_frame, regnum, regnum);
    }
}

/* Implement the "this_id" method of struct frame_unwind using
   the standard Windows x64 SEH info.  */

static void
amd64_windows_frame_this_id (frame_info_ptr this_frame, void **this_cache,
		   struct frame_id *this_id)
{
  struct amd64_windows_frame_cache *cache =
    amd64_windows_frame_cache (this_frame, this_cache);

  *this_id = frame_id_build (cache->prev_sp,
			     cache->image_base + cache->start_rva);
}

/* Windows x64 SEH unwinder.  */

static const struct frame_unwind amd64_windows_frame_unwind =
{
  "amd64 windows",
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  &amd64_windows_frame_this_id,
  &amd64_windows_frame_prev_register,
  NULL,
  default_frame_sniffer
};

/* Implement the "skip_prologue" gdbarch method.  */

static CORE_ADDR
amd64_windows_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  CORE_ADDR func_addr;
  CORE_ADDR unwind_info = 0;
  CORE_ADDR image_base, start_rva, end_rva;
  struct external_pex64_unwind_info ex_ui;

  /* Use prologue size from unwind info.  */
  if (amd64_windows_find_unwind_info (gdbarch, pc, &unwind_info,
				      &image_base, &start_rva, &end_rva) == 0)
    {
      if (unwind_info == 0)
	{
	  /* Leaf function.  */
	  return pc;
	}
      else if (target_read_memory (image_base + unwind_info,
				   (gdb_byte *) &ex_ui, sizeof (ex_ui)) == 0
	       && PEX64_UWI_VERSION (ex_ui.Version_Flags) == 1)
	return std::max (pc, image_base + start_rva + ex_ui.SizeOfPrologue);
    }

  /* See if we can determine the end of the prologue via the symbol
     table.  If so, then return either the PC, or the PC after
     the prologue, whichever is greater.  */
  if (find_pc_partial_function (pc, NULL, &func_addr, NULL))
    {
      CORE_ADDR post_prologue_pc
	= skip_prologue_using_sal (gdbarch, func_addr);

      if (post_prologue_pc != 0)
	return std::max (pc, post_prologue_pc);
    }

  return pc;
}

/* Check Win64 DLL jmp trampolines and find jump destination.  */

static CORE_ADDR
amd64_windows_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
{
  CORE_ADDR destination = 0;
  struct gdbarch *gdbarch = get_frame_arch (frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  /* Check for jmp *<offset>(%rip) (jump near, absolute indirect (/4)).  */
  if (pc && read_memory_unsigned_integer (pc, 2, byte_order) == 0x25ff)
    {
      /* Get opcode offset and see if we can find a reference in our data.  */
      ULONGEST offset
	= read_memory_unsigned_integer (pc + 2, 4, byte_order);

      /* Get address of function pointer at end of pc.  */
      CORE_ADDR indirect_addr = pc + offset + 6;

      struct minimal_symbol *indsym
	= (indirect_addr
	   ? lookup_minimal_symbol_by_pc (indirect_addr).minsym
	   : NULL);
      const char *symname = indsym ? indsym->linkage_name () : NULL;

      if (symname)
	{
	  if (startswith (symname, "__imp_")
	      || startswith (symname, "_imp_"))
	    destination
	      = read_memory_unsigned_integer (indirect_addr, 8, byte_order);
	}
    }

  return destination;
}

/* Implement the "auto_wide_charset" gdbarch method.  */

static const char *
amd64_windows_auto_wide_charset (void)
{
  return "UTF-16";
}

/* Common parts for gdbarch initialization for Windows and Cygwin on AMD64.  */

static void
amd64_windows_init_abi_common (gdbarch_info info, struct gdbarch *gdbarch)
{
  i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);

  /* The dwarf2 unwinder (appended very early by i386_gdbarch_init) is
     preferred over the SEH one.  The reasons are:
     - binaries without SEH but with dwarf2 debug info are correctly handled
       (although they aren't ABI compliant, gcc before 4.7 didn't emit SEH
       info).
     - dwarf3 DW_OP_call_frame_cfa is correctly handled (it can only be
       handled if the dwarf2 unwinder is used).

    The call to amd64_init_abi appends default unwinders, that aren't
    compatible with the SEH one.
  */
  frame_unwind_append_unwinder (gdbarch, &amd64_windows_frame_unwind);

  amd64_init_abi (info, gdbarch,
		  amd64_target_description (X86_XSTATE_SSE_MASK, false));

  /* Function calls.  */
  set_gdbarch_push_dummy_call (gdbarch, amd64_windows_push_dummy_call);
  set_gdbarch_return_value (gdbarch, amd64_windows_return_value);
  set_gdbarch_skip_main_prologue (gdbarch, amd64_skip_main_prologue);
  set_gdbarch_skip_trampoline_code (gdbarch,
				    amd64_windows_skip_trampoline_code);

  set_gdbarch_skip_prologue (gdbarch, amd64_windows_skip_prologue);

  tdep->gregset_reg_offset = amd64_windows_gregset_reg_offset;
  tdep->gregset_num_regs = ARRAY_SIZE (amd64_windows_gregset_reg_offset);
  tdep->sizeof_gregset = AMD64_WINDOWS_SIZEOF_GREGSET;
  tdep->sizeof_fpregset = 0;

  /* Core file support.  */
  set_gdbarch_core_xfer_shared_libraries
    (gdbarch, windows_core_xfer_shared_libraries);
  set_gdbarch_core_pid_to_str (gdbarch, windows_core_pid_to_str);

  set_gdbarch_auto_wide_charset (gdbarch, amd64_windows_auto_wide_charset);
}

/* gdbarch initialization for Windows on AMD64.  */

static void
amd64_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  amd64_windows_init_abi_common (info, gdbarch);
  windows_init_abi (info, gdbarch);

  /* On Windows, "long"s are only 32bit.  */
  set_gdbarch_long_bit (gdbarch, 32);
}

/* gdbarch initialization for Cygwin on AMD64.  */

static void
amd64_cygwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  amd64_windows_init_abi_common (info, gdbarch);
  cygwin_init_abi (info, gdbarch);
}

static gdb_osabi
amd64_windows_osabi_sniffer (bfd *abfd)
{
  const char *target_name = bfd_get_target (abfd);

  if (!streq (target_name, "pei-x86-64"))
    return GDB_OSABI_UNKNOWN;

  if (is_linked_with_cygwin_dll (abfd))
    return GDB_OSABI_CYGWIN;

  return GDB_OSABI_WINDOWS;
}

static enum gdb_osabi
amd64_cygwin_core_osabi_sniffer (bfd *abfd)
{
  const char *target_name = bfd_get_target (abfd);

  /* Cygwin uses elf core dumps.  Do not claim all ELF executables,
     check whether there is a .reg section of proper size.  */
  if (strcmp (target_name, "elf64-x86-64") == 0)
    {
      asection *section = bfd_get_section_by_name (abfd, ".reg");
      if (section != nullptr
	  && bfd_section_size (section) == AMD64_WINDOWS_SIZEOF_GREGSET)
	return GDB_OSABI_CYGWIN;
    }

  return GDB_OSABI_UNKNOWN;
}

void _initialize_amd64_windows_tdep ();
void
_initialize_amd64_windows_tdep ()
{
  gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, GDB_OSABI_WINDOWS,
			  amd64_windows_init_abi);
  gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, GDB_OSABI_CYGWIN,
			  amd64_cygwin_init_abi);

  gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour,
				  amd64_windows_osabi_sniffer);

  /* Cygwin uses elf core dumps.  */
  gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour,
				  amd64_cygwin_core_osabi_sniffer);

}
