/* Structured Exception Handling (SEH) runtime interface routines.
   Copyright (C) 2010-2021 Free Software Foundation, Inc.

   This file is part of GCC.

   GCC 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, or (at your option)
   any later version.

   GCC 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.

   Under Section 7 of GPL version 3, you are granted additional
   permissions described in the GCC Runtime Library Exception, version
   3.1, as published by the Free Software Foundation.

   You should have received a copy of the GNU General Public License and
   a copy of the GCC Runtime Library Exception along with this program;
   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
   <http://www.gnu.org/licenses/>.  */

#include "tconfig.h"
#include "tsystem.h"
#include "coretypes.h"
#include "tm.h"
#include "unwind.h"

#if defined (__SEH__) && !defined (__USING_SJLJ_EXCEPTIONS__)

/* At the moment everything is written for x64, but in theory this could
   also be used for i386, arm, mips and other extant embedded Windows.  */
#ifndef __x86_64__
#error "Unsupported architecture."
#endif

/* Define GCC's exception codes.  See
     http://msdn.microsoft.com/en-us/library/het71c37(v=VS.80).aspx
   In particular, MS defines bits:
     [31:30] = 3 (error), 2 (warning), 1 (info), 0 (success)
     [29]    = 1 (user-defined)
     [28]    = 0 (reserved)
   We define bits:
     [24:27] = type
     [0:23]  = magic
   We set "magic" to "GCC", which is similar to MVC++ which uses "msc"
   as the low 3 bytes of its user-defined codes for C++ exceptions.

   We define the ExceptionInformation entries as follows:
     [0] = _Unwind_Exception pointer
     [1] = target frame
     [2] = target ip
     [3] = target rdx
*/

#define STATUS_USER_DEFINED		(1U << 29)

#define GCC_MAGIC			(('G' << 16) | ('C' << 8) | 'C')
#define GCC_EXCEPTION(TYPE)		\
       (STATUS_USER_DEFINED | ((TYPE) << 24) | GCC_MAGIC)

#define STATUS_GCC_THROW		GCC_EXCEPTION (0)
#define STATUS_GCC_UNWIND		GCC_EXCEPTION (1)
#define STATUS_GCC_FORCED		GCC_EXCEPTION (2)


struct _Unwind_Context
{
  _Unwind_Word cfa;
  _Unwind_Word ra;
  _Unwind_Word reg[2];
  PDISPATCHER_CONTEXT disp;
};

/* Get the value of register INDEX as saved in CONTEXT.  */

_Unwind_Word
_Unwind_GetGR (struct _Unwind_Context *c, int index)
{
  if (index < 0 || index >= 2)
    abort ();
  return c->reg[index];
}

/* Overwrite the saved value for register INDEX in CONTEXT with VAL.  */

void
_Unwind_SetGR (struct _Unwind_Context *c, int index, _Unwind_Word val)
{
  if (index < 0 || index >= 2)
    abort ();
  c->reg[index] = val;
}

/* Get the value of the CFA as saved in CONTEXT.  */

_Unwind_Word
_Unwind_GetCFA (struct _Unwind_Context *c)
{
  return c->cfa;
}

/* Retrieve the return address for CONTEXT.  */

_Unwind_Ptr
_Unwind_GetIP (struct _Unwind_Context *c)
{
  return c->ra;
}

/* Retrieve the return address and flag whether that IP is before
   or after first not yet fully executed instruction.  */

_Unwind_Ptr
_Unwind_GetIPInfo (struct _Unwind_Context *c, int *ip_before_insn)
{
  /* ??? Is there a concept of a signal context properly?  There's
     obviously an UNWP_PUSH_MACHFRAME opcode, but the runtime might
     have arranged for that not to matter, really.  */
  *ip_before_insn = 0;
  return c->ra;
}

/* Overwrite the return address for CONTEXT with VAL.  */

void
_Unwind_SetIP (struct _Unwind_Context *c, _Unwind_Ptr val)
{
  c->ra = val;
}

void *
_Unwind_GetLanguageSpecificData (struct _Unwind_Context *c)
{
  return c->disp->HandlerData;
}

_Unwind_Ptr
_Unwind_GetRegionStart (struct _Unwind_Context *c)
{
  return c->disp->FunctionEntry->BeginAddress + c->disp->ImageBase;
}

void *
_Unwind_FindEnclosingFunction (void *pc)
{
  PRUNTIME_FUNCTION entry;
  ULONG64 ImageBase;

  entry = RtlLookupFunctionEntry ((ULONG64)pc, &ImageBase, NULL);

  return (entry ? (void *)(entry->BeginAddress + ImageBase) : NULL);
}

_Unwind_Ptr
_Unwind_GetDataRelBase (struct _Unwind_Context *c ATTRIBUTE_UNUSED)
{
  return 0;
}

_Unwind_Ptr
_Unwind_GetTextRelBase (struct _Unwind_Context *c)
{
  return c->disp->ImageBase;
}


/* The two-phase unwind process that GCC uses is ordered differently
   from the two-phase unwind process that SEH uses.  The mechansism
   that GCC uses is to have the filter return _URC_HANDER_FOUND; the
   mechanism that SEH uses is for the filter function call back into
   the unwinder.

   An Ideal port to SEH would have GCC emit handler functions that
   can be called, given a pointer to the "EstablisherFrame" (i.e.
   the frame pointer base of the user-level function) can manipulate
   the user-level variables within the user-level function's stack
   frame.  Once done manipulating the variables, it would return
   a ExceptionContinueSearch, and the unwind process would continue.

   GCC has always done things a bit differently.  We continue to
   transfer control back into the user-level function which, once
   done manipulating the user-level variables, re-throws the exception.  */

/* The "real" language-specific personality handler forwards to here
   where we handle the MS SEH state and transforms it into the GCC
   unwind state as per GCC's <unwind.h>, at which point we defer to
   the regular language-specfic exception handler, which is passed in.  */

EXCEPTION_DISPOSITION
_GCC_specific_handler (PEXCEPTION_RECORD ms_exc, void *this_frame,
		       PCONTEXT ms_orig_context, PDISPATCHER_CONTEXT ms_disp,
		       _Unwind_Personality_Fn gcc_per)
{
  DWORD ms_flags = ms_exc->ExceptionFlags;
  DWORD ms_code = ms_exc->ExceptionCode;

  struct _Unwind_Exception *gcc_exc
    = (struct _Unwind_Exception *) ms_exc->ExceptionInformation[0];
  struct _Unwind_Context gcc_context;
  _Unwind_Action gcc_action;
  _Unwind_Reason_Code gcc_reason;

  if (ms_flags & EXCEPTION_TARGET_UNWIND)
    {
      /* This frame is known to be the target frame.  We've already
         "installed" the target_ip and RAX value via the arguments
         to RtlUnwindEx.  All that's left is to set the RDX value
         and "continue" to have the context installed.  */
      ms_disp->ContextRecord->Rdx = ms_exc->ExceptionInformation[3];
      return ExceptionContinueSearch;
    }

  if (ms_code == STATUS_GCC_UNWIND)
    {
      /* This is a colliding exception that we threw so that we could
         cancel the already in-flight exception and stop in a frame
	 that wanted to perform some unwind action.  The only relevant
	 test is that we're the target frame.  */
      if (ms_exc->ExceptionInformation[1] == (_Unwind_Ptr) this_frame)
	{
	  RtlUnwindEx (this_frame, (PVOID) ms_exc->ExceptionInformation[2],
		       ms_exc, gcc_exc, ms_orig_context,
		       ms_disp->HistoryTable);
	  abort ();
	}
      return ExceptionContinueSearch;
    }

  gcc_context.cfa = ms_disp->ContextRecord->Rsp;
  gcc_context.ra = ms_disp->ControlPc;
  gcc_context.reg[0] = 0xdeadbeef;	/* These are write-only.  */
  gcc_context.reg[1] = 0xdeadbeef;
  gcc_context.disp = ms_disp;

  if (ms_code == STATUS_GCC_FORCED)
    {
       _Unwind_Stop_Fn stop = (_Unwind_Stop_Fn) gcc_exc->private_[0];
       void *stop_argument = (void *) gcc_exc->private_[4];

       gcc_action = _UA_FORCE_UNWIND | _UA_CLEANUP_PHASE;

       stop (1, gcc_action, gcc_exc->exception_class, gcc_exc,
             &gcc_context, stop_argument);

       goto phase2;
    }

  /* ??? TODO: handling non-gcc user-defined exceptions as foreign.  */
  if (ms_code != STATUS_GCC_THROW)
    return ExceptionContinueSearch;

  if (ms_flags & (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND))
    {
      /* This is Phase 2.  */
      /* We know this isn't the target frame because we've already tested
	 EXCEPTION_TARGET_UNWIND.  The remaining possibility is that the
	 gcc personality has unwind code to run.  */

      gcc_action = _UA_CLEANUP_PHASE;
    phase2:
      gcc_reason = gcc_per (1, gcc_action, gcc_exc->exception_class,
			    gcc_exc, &gcc_context);

      if (gcc_reason == _URC_CONTINUE_UNWIND)
	return ExceptionContinueSearch;

      if (gcc_reason == _URC_INSTALL_CONTEXT)
	{
	  /* Scratch space for the bits for the unwind catch.  */
	  ms_exc->ExceptionInformation[1] = (_Unwind_Ptr) this_frame;
	  ms_exc->ExceptionInformation[2] = gcc_context.ra;
	  ms_exc->ExceptionInformation[3] = gcc_context.reg[1];

	  /* Cancel the current exception by raising another.  */
	  RaiseException (STATUS_GCC_UNWIND, EXCEPTION_NONCONTINUABLE,
			  4, ms_exc->ExceptionInformation);

	  /* Is RaiseException declared noreturn?  */
	}

      /* In _Unwind_RaiseException_Phase2 we return _URC_FATAL_PHASE2_ERROR. */
    }
  else
    {
      /* This is Phase 1.  */
      gcc_reason = gcc_per (1, _UA_SEARCH_PHASE, gcc_exc->exception_class,
			    gcc_exc, &gcc_context);

      if (gcc_reason == _URC_CONTINUE_UNWIND)
	return ExceptionContinueSearch;

      if (gcc_reason == _URC_HANDLER_FOUND)
	{
	  /* We really need some of the information that GCC's personality
	     routines compute during phase 2 right now, like the target IP.
	     Go ahead and ask for it now, and cache it.  */
	  gcc_reason = gcc_per (1, _UA_CLEANUP_PHASE | _UA_HANDLER_FRAME,
				gcc_exc->exception_class, gcc_exc,
				&gcc_context);
	  if (gcc_reason != _URC_INSTALL_CONTEXT)
	    abort ();

	  gcc_exc->private_[1] = (_Unwind_Ptr) this_frame;
	  gcc_exc->private_[2] = gcc_context.ra;
	  gcc_exc->private_[3] = gcc_context.reg[1];

	  ms_exc->NumberParameters = 4;
	  ms_exc->ExceptionInformation[1] = (_Unwind_Ptr) this_frame;
	  ms_exc->ExceptionInformation[2] = gcc_context.ra;
	  ms_exc->ExceptionInformation[3] = gcc_context.reg[1];

	  /* Begin phase 2.  Perform the unwinding.  */
	  RtlUnwindEx (this_frame, (PVOID)gcc_context.ra, ms_exc,
		       (PVOID)gcc_context.reg[0], ms_orig_context,
		       ms_disp->HistoryTable);
	}

      /* In _Unwind_RaiseException we return _URC_FATAL_PHASE1_ERROR.  */
    }
  abort ();
}

/* Raise an exception, passing along the given exception object.  */

_Unwind_Reason_Code
_Unwind_RaiseException (struct _Unwind_Exception *exc)
{
  memset (exc->private_, 0, sizeof (exc->private_));

  /* The ExceptionInformation array will have only 1 element, EXC.  */
  RaiseException (STATUS_GCC_THROW, 0, 1, (ULONG_PTR *)&exc);

  /* The exception handler installed in crt0 will continue any GCC
     exception that reaches there (and isn't marked non-continuable).
     Returning allows the C++ runtime to call std::terminate.  */
  return _URC_END_OF_STACK;
}

/* Resume propagation of an existing exception.  This is used after
   e.g. executing cleanup code, and not to implement rethrowing.  */

void
_Unwind_Resume (struct _Unwind_Exception *gcc_exc)
{
  UNWIND_HISTORY_TABLE ms_history;
  EXCEPTION_RECORD ms_exc;
  CONTEXT ms_context;

  memset (&ms_exc, 0, sizeof(ms_exc));
  memset (&ms_history, 0, sizeof(ms_history));

  /* ??? Not 100% perfect, since we aren't passing on the *original*
     exception context, but should be good enough.  */
  ms_exc.ExceptionCode = STATUS_GCC_THROW;
  ms_exc.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
  ms_exc.NumberParameters = 4;
  ms_exc.ExceptionInformation[0] = (ULONG_PTR) gcc_exc;
  ms_exc.ExceptionInformation[1] = gcc_exc->private_[1];
  ms_exc.ExceptionInformation[2] = gcc_exc->private_[2];
  ms_exc.ExceptionInformation[3] = gcc_exc->private_[3];

  ms_context.ContextFlags = CONTEXT_ALL;
  RtlCaptureContext (&ms_context);

  RtlUnwindEx ((void *) gcc_exc->private_[1], (PVOID)gcc_exc->private_[2],
	       &ms_exc, gcc_exc, &ms_context, &ms_history);

  /* Is RtlUnwindEx declared noreturn?  */
  abort ();
}

static _Unwind_Reason_Code
_Unwind_ForcedUnwind_Phase2 (struct _Unwind_Exception *exc)
{
  _Unwind_Stop_Fn stop;
  void * stop_argument;

  RaiseException (STATUS_GCC_FORCED, 0, 1, (ULONG_PTR *)&exc);

  /* If we get here, we got to top-of-stack.  */
  /* ??? We no longer have a context pointer to pass in.  */

  stop = (_Unwind_Stop_Fn) exc->private_[0];
  stop_argument = (void *) exc->private_[4];
  stop (1, _UA_FORCE_UNWIND | _UA_CLEANUP_PHASE | _UA_END_OF_STACK,
	exc->exception_class, exc, NULL, stop_argument);

  return _UA_END_OF_STACK;
}

_Unwind_Reason_Code
_Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc)
{
  if (exc->private_[0] == 0)
    _Unwind_RaiseException (exc);
  else
    _Unwind_ForcedUnwind_Phase2 (exc);
  abort ();
}

/* Raise an exception for forced unwinding.  */

_Unwind_Reason_Code
_Unwind_ForcedUnwind (struct _Unwind_Exception *exc,
		      _Unwind_Stop_Fn stop, void * stop_argument)
{
  /* ??? This is a hack that only works with _GCC_specific_handler.
     There's no way to invoke STOP within frames that use a different
     exception handler.  This is essentially just good enough to run
     the code within the gcc testsuite.  */

  memset (exc->private_, 0, sizeof (exc->private_));
  exc->private_[0] = (_Unwind_Ptr) stop;
  exc->private_[4] = (_Unwind_Ptr) stop_argument;

  return _Unwind_ForcedUnwind_Phase2 (exc);
}

/* A convenience function that calls the exception_cleanup field.  */

void
_Unwind_DeleteException (struct _Unwind_Exception *exc)
{
  if (exc->exception_cleanup)
    (*exc->exception_cleanup) (_URC_FOREIGN_EXCEPTION_CAUGHT, exc);
}

/* Perform stack backtrace through unwind data.  */

_Unwind_Reason_Code
_Unwind_Backtrace(_Unwind_Trace_Fn trace,
		  void *trace_argument)
{
  UNWIND_HISTORY_TABLE ms_history;
  CONTEXT ms_context;
  struct _Unwind_Context gcc_context;
  DISPATCHER_CONTEXT disp_context;

  memset (&ms_history, 0, sizeof(ms_history));
  memset (&gcc_context, 0, sizeof(gcc_context));
  memset (&disp_context, 0, sizeof(disp_context));

  ms_context.ContextFlags = CONTEXT_ALL;
  RtlCaptureContext (&ms_context);

  gcc_context.disp = &disp_context;
  gcc_context.disp->ContextRecord = &ms_context;
  gcc_context.disp->HistoryTable = &ms_history;

  while (1)
    {
      gcc_context.disp->ControlPc = ms_context.Rip;
      gcc_context.disp->FunctionEntry
	= RtlLookupFunctionEntry (ms_context.Rip, &gcc_context.disp->ImageBase,
				  &ms_history);

      if (!gcc_context.disp->FunctionEntry)
	return _URC_END_OF_STACK;

      gcc_context.disp->LanguageHandler
	= RtlVirtualUnwind (0, gcc_context.disp->ImageBase, ms_context.Rip,
			    gcc_context.disp->FunctionEntry, &ms_context,
			    &gcc_context.disp->HandlerData,
			    &gcc_context.disp->EstablisherFrame, NULL);

      /* Set values that the callback can inspect via _Unwind_GetIP
       * and _Unwind_GetCFA. */
      gcc_context.ra = ms_context.Rip;
      gcc_context.cfa = ms_context.Rsp;

      /* Call trace function.  */
      if (trace (&gcc_context, trace_argument) != _URC_NO_REASON)
	return _URC_FATAL_PHASE1_ERROR;

      /* ??? Check for invalid stack pointer.  */
      if (ms_context.Rip == 0)
	return _URC_END_OF_STACK;
    }
}
#endif /* __SEH__  && !defined (__USING_SJLJ_EXCEPTIONS__)  */
