/* Copyright (C) 2009-2023 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,
			    struct value **read_value, const gdb_byte *writebuf)
{
  int len = type->length ();
  int regnum = -1;

  gdb_byte *readbuf = nullptr;
  if (read_value != nullptr)
    {
      *read_value = allocate_value (type);
      readbuf = value_contents_raw (*read_value).data ();
    }

  /* 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_as_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);

}
