/* Definitions for Dwarf2 EH unwind support for Windows32 targets
   Copyright (C) 2007-2023 Free Software Foundation, Inc.
   Contributed by Pascal Obry  <obry@adacore.com>

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/>.  */


/* This file implements the md_fallback_frame_state_for routine for
   Windows, triggered when the GCC table based unwinding process hits a
   frame for which no unwind info has been registered. This typically
   occurs when raising an exception from a signal handler, because the
   handler is actually called from the OS kernel.

   The basic idea is to detect that we are indeed trying to unwind past a
   signal handler and to fill out the GCC internal unwinding structures for
   the OS kernel frame as if it had been directly called from the
   interrupted context.

   This is all assuming that the code to set the handler asked the kernel
   to pass a pointer to such context information.

   There is three main parts.

   1) The first thing to do is to check if we are in a signal context. If
      not we can just return as there is nothing to do. We are probably on
      some foreign code for which no unwind frame can be found. If this is
      a call from the Windows signal handler, then:

   2) We must get the signal context information. 

      * With the standard exception filter:

      This is on Windows pointed to by an EXCEPTION_POINTERS. We know that
      the signal handle will call an UnhandledExceptionFilter with this
      parameter. The spec for this routine is:

         LONG WINAPI UnhandledExceptionFilter(struct _EXCEPTION_POINTERS*);

      So the pointer to struct _EXCEPTION_POINTERS must be somewhere on the
      stack.

      This was found experimentally to always be at offset 0 of the context
      frame in all cases handled by this implementation.

      * With the SEH exception handler:

      In this case the signal context is directly on the stack as the SEH
      exception handler has the following prototype:

         DWORD
         SEH_error_handler (PEXCEPTION_RECORD ExceptionRecord,
                            PVOID EstablisherFrame,
                            PCONTEXT ContextRecord,
                            PVOID DispatcherContext)

      This was found experimentally to always be at offset 56 of the
      context frame in all cases handled by this implementation.

   3) When we have the signal context we just have to save some registers
      and set the return address based on the program counter (Eip).

   Note that this implementation follows closely the same principles as the
   GNU/Linux and OSF ones.  */

#ifndef __MINGW64__

#define WIN32_MEAN_AND_LEAN
#include <windows.h>
/* Patterns found experimentally to be on a Windows signal handler  */

/* In a standard exception filter  */

#define SIG_PAT1 \
      (pc_[-2] == 0xff && pc_[-1] == 0xd0     /* call %eax           */ \
      && pc_[0] == 0x83 && pc_[1] == 0xf8)    /* cmp 0xdepl,%eax     */

#define SIG_PAT2 \
        (pc_[-5] == 0xe8 && pc_[-4] == 0x68   /* call (depl16)       */ \
         && pc_[0] == 0xc3)                   /* ret                 */

/* In a Win32 SEH handler  */

#define SIG_SEH1 \
        (pc_[-5] == 0xe8                      /* call addr           */ \
         && pc_[0] == 0x83 && pc_[1] == 0xc4  /* add 0xval,%esp      */ \
         && pc_[3] == 0xb8)                   /* mov 0xval,%eax      */

#define SIG_SEH2 \
        (pc_[-5] == 0x8b && pc_[-4] == 0x4d   /* mov depl(%ebp),%ecx */ \
         && pc_[0] == 0x64 && pc_[1] == 0x8b) /* mov %fs:(0),<reg>   */ \

/* In the GCC alloca (stack probing)  */

#define SIG_ALLOCA \
          (pc_[-1] == 0x83                    /* orl $0x0,(%ecx)     */ \
	   && pc_[0] == 0x9 && pc_[1] == 0                              \
	   && pc_[2] == 0x2d && pc_[3] == 0   /* subl $0x1000,%eax   */ \
	   && pc_[4] == 0x10 && pc_[5] == 0)


#define MD_FALLBACK_FRAME_STATE_FOR i386_w32_fallback_frame_state

static _Unwind_Reason_Code
i386_w32_fallback_frame_state (struct _Unwind_Context *context, 
			       _Unwind_FrameState *fs)

{
  void * ctx_ra_  = (void *)(context->ra);  /* return address */
  void * ctx_cfa_ = (void *)(context->cfa); /* context frame address */
  unsigned char * pc_ = (unsigned char *) ctx_ra_;

  /* In the test below we look for two specific patterns found
     experimentally to be in the Windows signal handler.  */
  if (SIG_PAT1 || SIG_PAT2 || SIG_SEH1 || SIG_SEH2)
    {
      PEXCEPTION_POINTERS weinfo_;
      PCONTEXT proc_ctx_;
      long new_cfa_;

      if (SIG_SEH1) 
	proc_ctx_ = (PCONTEXT) (*(int*)(ctx_cfa_ + 56));
      else if (SIG_SEH2)
	proc_ctx_ = (PCONTEXT) (*(int*)(ctx_cfa_ + 8));
      else
	{
	  weinfo_ = (PEXCEPTION_POINTERS) (*(int*)ctx_cfa_);
	  proc_ctx_ = weinfo_->ContextRecord;
	}

      /* The new context frame address is the stack pointer.  */
      new_cfa_ = proc_ctx_->Esp;
      fs->regs.cfa_how = CFA_REG_OFFSET;
      fs->regs.cfa_reg = __builtin_dwarf_sp_column();
      fs->regs.cfa_offset = new_cfa_ - (long) ctx_cfa_;

      /* Restore registers.  */
      fs->regs.how[0] = REG_SAVED_OFFSET;
      fs->regs.reg[0].loc.offset = (long)&proc_ctx_->Eax - new_cfa_;
      fs->regs.how[3] = REG_SAVED_OFFSET;
      fs->regs.reg[3].loc.offset = (long)&proc_ctx_->Ebx - new_cfa_;
      fs->regs.how[1] = REG_SAVED_OFFSET;
      fs->regs.reg[1].loc.offset = (long)&proc_ctx_->Ecx - new_cfa_;
      fs->regs.how[2] = REG_SAVED_OFFSET;
      fs->regs.reg[2].loc.offset = (long)&proc_ctx_->Edx - new_cfa_;
      fs->regs.how[6] = REG_SAVED_OFFSET;
      fs->regs.reg[6].loc.offset = (long)&proc_ctx_->Esi - new_cfa_;
      fs->regs.how[7] = REG_SAVED_OFFSET;
      fs->regs.reg[7].loc.offset = (long)&proc_ctx_->Edi - new_cfa_;
      fs->regs.how[5] = REG_SAVED_OFFSET;
      fs->regs.reg[5].loc.offset = (long)&proc_ctx_->Ebp - new_cfa_;
      fs->regs.how[8] = REG_SAVED_OFFSET;
      fs->regs.reg[8].loc.offset = (long)&proc_ctx_->Eip - new_cfa_;
      fs->retaddr_column = 8;
      fs->signal_frame = 1;

      return _URC_NO_REASON;
    }

  /* Unwinding through _alloca, propagating from a trap triggered by
     one of it's probes prior to the real SP adjustment. The only
     operations of interest performed is "pushl %ecx", followed by
     ecx clobbering.  */
  else if (SIG_ALLOCA) 
    {
      /* Only one push between entry in _alloca and the probe trap.  */ 
      long new_cfa_ = (long) ctx_cfa_ + 4;

      fs->regs.cfa_how = CFA_REG_OFFSET;
      fs->regs.cfa_reg = __builtin_dwarf_sp_column();
      fs->regs.cfa_offset = new_cfa_ - (long) ctx_cfa_;

      /* The saved value of %ecx is at CFA - 4 */
      fs->regs.how[1] = REG_SAVED_OFFSET;
      fs->regs.reg[1].loc.offset = -4;

      /* and what is stored at the CFA is the return address.  */
      fs->retaddr_column = 8;
      fs->regs.how[8] = REG_SAVED_OFFSET;
      fs->regs.reg[8].loc.offset = 0;
      fs->signal_frame = 1;

      return _URC_NO_REASON;
    }
  else
    return _URC_END_OF_STACK;
}

#endif /* !__MINGW64__ */
