/* Structured Exception Handling (SEH) runtime interface routines.
   Copyright (C) 2010-2024 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)
    return _Unwind_RaiseException (exc);

  _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__)  */
