/* Common unwinding code for ARM EABI and C6X.
   Copyright (C) 2004-2024 Free Software Foundation, Inc.
   Contributed by Paul Brook

   This file 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.

   This file 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 "unwind.h"

/* Used for SystemTap unwinder probe.  */
#ifdef HAVE_SYS_SDT_H
#include <sys/sdt.h>
#endif

#if __FDPIC__
/* Load r7 with rt_sigreturn value.  */
#define ARM_SET_R7_RT_SIGRETURN		0xe3a070ad	/* mov   r7, #0xad */
#define THUMB2_SET_R7_RT_SIGRETURN	0x07adf04f	/* mov.w r7, #0xad */

/* FDPIC jump to restorer sequence.  */
#define FDPIC_LDR_R12_WITH_FUNCDESC	0xe59fc004	/* ldr   r12, [pc, #4] */
#define FDPIC_LDR_R9_WITH_GOT		0xe59c9004	/* ldr   r9, [r12, #4] */
#define FDPIC_LDR_PC_WITH_RESTORER	0xe59cf000	/* ldr   pc, [r12] */
#define FDPIC_T2_LDR_R12_WITH_FUNCDESC  0xc008f8df	/* ldr.w r12, [pc, #8] */
#define FDPIC_T2_LDR_R9_WITH_GOT	0x9004f8dc	/* ldr.w r9, [r12, #4] */
#define FDPIC_T2_LDR_PC_WITH_RESTORER   0xf000f8dc	/* ldr.w pc, [r12] */
#define FDPIC_FUNCDESC_OFFSET		12

/* Signal frame offsets.  */
#define ARM_NEW_RT_SIGFRAME_UCONTEXT	0x80
#define ARM_UCONTEXT_SIGCONTEXT		0x14
#define ARM_SIGCONTEXT_R0		0xc
#endif

/* Definitions for C++ runtime support routines.  We make these weak
   declarations to avoid pulling in libsupc++ unnecessarily.  */
typedef unsigned char bool;

typedef struct _ZSt9type_info type_info; /* This names C++ type_info type */
enum __cxa_type_match_result
  {
    ctm_failed = 0,
    ctm_succeeded = 1,
    ctm_succeeded_with_ptr_to_base = 2
  };

void __attribute__((weak)) __cxa_call_unexpected(_Unwind_Control_Block *ucbp);
bool __attribute__((weak)) __cxa_begin_cleanup(_Unwind_Control_Block *ucbp);
enum __cxa_type_match_result __attribute__((weak)) __cxa_type_match
  (_Unwind_Control_Block *ucbp, const type_info *rttip,
   bool is_reference, void **matched_object);

_Unwind_Ptr __attribute__((weak))
__gnu_Unwind_Find_exidx (_Unwind_Ptr, int *);

#define EXIDX_CANTUNWIND 1
#define uint32_highbit (((_uw) 1) << 31)

#define UCB_FORCED_STOP_FN(ucbp) ((ucbp)->unwinder_cache.reserved1)
#define UCB_PR_ADDR(ucbp) ((ucbp)->unwinder_cache.reserved2)
#define UCB_SAVED_CALLSITE_ADDR(ucbp) ((ucbp)->unwinder_cache.reserved3)
#define UCB_FORCED_STOP_ARG(ucbp) ((ucbp)->unwinder_cache.reserved4)
#define UCB_PR_GOT(ucbp) ((ucbp)->unwinder_cache.reserved5)

/* Unwind descriptors.  */

typedef struct
{
  _uw16 length;
  _uw16 offset;
} EHT16;

typedef struct
{
  _uw length;
  _uw offset;
} EHT32;

/* An exception index table entry.  */

typedef struct __EIT_entry
{
  _uw fnoffset;
  _uw content;
} __EIT_entry;

#ifdef __FDPIC__

/* Only used in FDPIC case.  */
struct funcdesc_t
{
  unsigned int ptr;
  unsigned int got;
};
#endif

/* Assembly helper functions.  */

/* Restore core register state.  Never returns.  */
void __attribute__((noreturn)) restore_core_regs (struct core_regs *);


/* Restore coprocessor state after phase1 unwinding.  */
static void restore_non_core_regs (phase1_vrs * vrs);

/* A better way to do this would probably be to compare the absolute address
   with a segment relative relocation of the same symbol.  */

extern int __text_start;
extern int __data_start;

/* The exception index table location.  */
extern __EIT_entry __exidx_start;
extern __EIT_entry __exidx_end;

/* Core unwinding functions.  */

/* Calculate the address encoded by a 31-bit self-relative offset at address
   P.  */
static inline _uw selfrel_offset31 (const _uw *p);

static _uw __gnu_unwind_get_pr_addr (int idx);

static void _Unwind_DebugHook (void *, void *)
  __attribute__ ((__noinline__, __used__, __noclone__));

/* This function is called during unwinding.  It is intended as a hook
   for a debugger to intercept exceptions.  CFA is the CFA of the
   target frame.  HANDLER is the PC to which control will be
   transferred.  */

static void
_Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
		   void *handler __attribute__ ((__unused__)))
{
  /* We only want to use stap probes starting with v3.  Earlier
     versions added too much startup cost.  */
#if defined (HAVE_SYS_SDT_H) && defined (STAP_PROBE2) && _SDT_NOTE_TYPE >= 3
  STAP_PROBE2 (libgcc, unwind, cfa, handler);
#else
  asm ("");
#endif
}

/* This is a wrapper to be called when we need to restore core registers.
   It will call `_Unwind_DebugHook' before restoring the registers, thus
   making it possible to intercept and debug exceptions.

   When calling `_Unwind_DebugHook', the first argument (the CFA) is zero
   because we are not interested in it.  However, it must be there (even
   being zero) because GDB expects to find it when using the probe.  */

#define uw_restore_core_regs(TARGET, CORE)				      \
  do									      \
    {									      \
      void *handler = __builtin_frob_return_addr ((void *) VRS_PC (TARGET));  \
      _Unwind_DebugHook (0, handler);					      \
      restore_core_regs (CORE);						      \
    }									      \
  while (0)

/* Perform a binary search for RETURN_ADDRESS in TABLE.  The table contains
   NREC entries.  */

static const __EIT_entry *
search_EIT_table (const __EIT_entry * table, int nrec, _uw return_address)
{
  _uw next_fn;
  _uw this_fn;
  int n, left, right;

  if (nrec == 0)
    return (__EIT_entry *) 0;

  left = 0;
  right = nrec - 1;

  while (1)
    {
      n = (left + right) / 2;
      this_fn = selfrel_offset31 (&table[n].fnoffset);
      if (n != nrec - 1)
	next_fn = selfrel_offset31 (&table[n + 1].fnoffset) - 1;
      else
	next_fn = (_uw)0 - 1;

      if (return_address < this_fn)
	{
	  if (n == left)
	    return (__EIT_entry *) 0;
	  right = n - 1;
	}
      else if (return_address <= next_fn)
	return &table[n];
      else
	left = n + 1;
    }
}

#if __FDPIC__
/* VFP is not restored, but this is sufficient to allow unwinding.  */
static _Unwind_Reason_Code
__gnu_personality_sigframe_fdpic (_Unwind_State state,
				  _Unwind_Control_Block *ucbp,
				  _Unwind_Context *context)
{
    unsigned int sp;
    unsigned int pc;
    unsigned int funcdesc;
    unsigned int handler;
    unsigned int first_handler_instruction;
    int i;

    _Unwind_VRS_Get (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, &sp);
    _Unwind_VRS_Get (context, _UVRSC_CORE, R_PC, _UVRSD_UINT32, &pc);

    funcdesc = *(unsigned int *)((pc & ~1) + FDPIC_FUNCDESC_OFFSET);
    handler = *(unsigned int *)(funcdesc);
    first_handler_instruction = *(unsigned int *)(handler & ~1);

    /* Adjust SP to point to the start of registers according to
       signal type.  */
    if (first_handler_instruction == ARM_SET_R7_RT_SIGRETURN
	|| first_handler_instruction == THUMB2_SET_R7_RT_SIGRETURN)
	sp += ARM_NEW_RT_SIGFRAME_UCONTEXT
	  + ARM_UCONTEXT_SIGCONTEXT
	  + ARM_SIGCONTEXT_R0;
    else
	sp += ARM_UCONTEXT_SIGCONTEXT
	  + ARM_SIGCONTEXT_R0;
    /* Restore regs saved on stack by the kernel.  */
    for (i = 0; i < 16; i++)
	_Unwind_VRS_Set (context, _UVRSC_CORE, i, _UVRSD_UINT32, (void *)(sp + 4 * i));

    return _URC_CONTINUE_UNWIND;
}
#endif

/* Find the exception index table eintry for the given address.
   Fill in the relevant fields of the UCB.
   Returns _URC_FAILURE if an error occurred, _URC_OK on success.  */

static _Unwind_Reason_Code
get_eit_entry (_Unwind_Control_Block *ucbp, _uw return_address)
{
  const __EIT_entry * eitp;
  int nrec;
  
  /* The return address is the address of the instruction following the
     call instruction (plus one in thumb mode).  If this was the last
     instruction in the function the address will lie in the following
     function.  Subtract 2 from the address so that it points within the call
     instruction itself.  */
  return_address -= 2;

  if (__gnu_Unwind_Find_exidx)
    {
      eitp = (const __EIT_entry *) __gnu_Unwind_Find_exidx (return_address,
							    &nrec);
      if (!eitp)
	{
#if __FDPIC__
	  /* If we are unwinding a signal handler then perhaps we have
	     reached a trampoline.  Try to detect jump to restorer
	     sequence.  */
	  _uw *pc = (_uw *)((return_address+2) & ~1);
	  if ((pc[0] == FDPIC_LDR_R12_WITH_FUNCDESC
	       && pc[1] == FDPIC_LDR_R9_WITH_GOT
	       && pc[2] == FDPIC_LDR_PC_WITH_RESTORER)
	      || (pc[0] == FDPIC_T2_LDR_R12_WITH_FUNCDESC
		  && pc[1] == FDPIC_T2_LDR_R9_WITH_GOT
		  && pc[2] == FDPIC_T2_LDR_PC_WITH_RESTORER))
	    {
	      struct funcdesc_t *funcdesc
		= (struct funcdesc_t *) &__gnu_personality_sigframe_fdpic;

	      UCB_PR_ADDR (ucbp) = funcdesc->ptr;
	      UCB_PR_GOT (ucbp) = funcdesc->got;

	      return _URC_OK;
	    }
#endif
	  UCB_PR_ADDR (ucbp) = 0;
	  return _URC_FAILURE;
	}
    }
  else
    {
      eitp = &__exidx_start;
      nrec = &__exidx_end - &__exidx_start;
    }

  eitp = search_EIT_table (eitp, nrec, return_address);

  if (!eitp)
    {
#if __FDPIC__
      /* If we are unwinding a signal handler then perhaps we have
	 reached a trampoline.  Try to detect jump to restorer
	 sequence.  */
      _uw *pc = (_uw *)((return_address+2) & ~1);
      if ((pc[0] == FDPIC_LDR_R12_WITH_FUNCDESC
	   && pc[1] == FDPIC_LDR_R9_WITH_GOT
	   && pc[2] == FDPIC_LDR_PC_WITH_RESTORER)
	  || (pc[0] == FDPIC_T2_LDR_R12_WITH_FUNCDESC
	      && pc[1] == FDPIC_T2_LDR_R9_WITH_GOT
	      && pc[2] == FDPIC_T2_LDR_PC_WITH_RESTORER))
	{
	  struct funcdesc_t *funcdesc
	    = (struct funcdesc_t *) &__gnu_personality_sigframe_fdpic;

	  UCB_PR_ADDR (ucbp) = funcdesc->ptr;
	  UCB_PR_GOT (ucbp) = funcdesc->got;

	  return _URC_OK;
	}
#endif
      UCB_PR_ADDR (ucbp) = 0;
      return _URC_FAILURE;
    }
  ucbp->pr_cache.fnstart = selfrel_offset31 (&eitp->fnoffset);

  /* Can this frame be unwound at all?  */
  if (eitp->content == EXIDX_CANTUNWIND)
    {
#if __FDPIC__
      /* If we are unwinding a signal handler then perhaps we have
	 reached a trampoline.  Try to detect jump to restorer
	 sequence.  */
      _uw *pc = (_uw *)((return_address+2) & ~1);
      if ((pc[0] == FDPIC_LDR_R12_WITH_FUNCDESC
	   && pc[1] == FDPIC_LDR_R9_WITH_GOT
	   && pc[2] == FDPIC_LDR_PC_WITH_RESTORER)
	  || (pc[0] == FDPIC_T2_LDR_R12_WITH_FUNCDESC
	      && pc[1] == FDPIC_T2_LDR_R9_WITH_GOT
	      && pc[2] == FDPIC_T2_LDR_PC_WITH_RESTORER))
	{
	  struct funcdesc_t *funcdesc
	    = (struct funcdesc_t *) &__gnu_personality_sigframe_fdpic;

	  UCB_PR_ADDR (ucbp) = funcdesc->ptr;
	  UCB_PR_GOT (ucbp) = funcdesc->got;

	  return _URC_OK;
	}
#endif
      UCB_PR_ADDR (ucbp) = 0;
      return _URC_END_OF_STACK;
    }

  /* Obtain the address of the "real" __EHT_Header word.  */

  if (eitp->content & uint32_highbit)
    {
      /* It is immediate data.  */
      ucbp->pr_cache.ehtp = (_Unwind_EHT_Header *)&eitp->content;
      ucbp->pr_cache.additional = 1;
    }
  else
    {
      /* The low 31 bits of the content field are a self-relative
	 offset to an _Unwind_EHT_Entry structure.  */
      ucbp->pr_cache.ehtp =
	(_Unwind_EHT_Header *) selfrel_offset31 (&eitp->content);
      ucbp->pr_cache.additional = 0;
    }

  /* Discover the personality routine address.  */
  if (*ucbp->pr_cache.ehtp & (1u << 31))
    {
      /* One of the predefined standard routines.  */
      _uw idx = (*(_uw *) ucbp->pr_cache.ehtp >> 24) & 0xf;
#if __FDPIC__
      {
	struct funcdesc_t *funcdesc
	  = (struct funcdesc_t *) __gnu_unwind_get_pr_addr (idx);
	if (funcdesc)
	  {
	    UCB_PR_ADDR (ucbp) = funcdesc->ptr;
	    UCB_PR_GOT (ucbp) = funcdesc->got;
	  }
	else
	  UCB_PR_ADDR (ucbp) = 0;
      }
#else
      UCB_PR_ADDR (ucbp) = __gnu_unwind_get_pr_addr (idx);
#endif
      if (UCB_PR_ADDR (ucbp) == 0)
	{
	  /* Failed */
	  return _URC_FAILURE;
	}
    } 
  else
    {
      /* Execute region offset to PR */
      UCB_PR_ADDR (ucbp) = selfrel_offset31 (ucbp->pr_cache.ehtp);
#if __FDPIC__
      UCB_PR_GOT (ucbp)
	= (unsigned int) _Unwind_gnu_Find_got ((_Unwind_Ptr) UCB_PR_ADDR (ucbp));
#endif
    }
  return _URC_OK;
}


/* Perform phase2 unwinding.  VRS is the initial virtual register state.  */

static void __attribute__((noreturn))
unwind_phase2 (_Unwind_Control_Block * ucbp, phase2_vrs * vrs)
{
  _Unwind_Reason_Code pr_result;

  do
    {
      /* Find the entry for this routine.  */
      if (get_eit_entry (ucbp, VRS_PC(vrs)) != _URC_OK)
	abort ();

      UCB_SAVED_CALLSITE_ADDR (ucbp) = VRS_PC(vrs);

      /* Call the pr to decide what to do.  */
#if __FDPIC__
      {
	volatile struct funcdesc_t funcdesc;
	funcdesc.ptr = UCB_PR_ADDR (ucbp);
	funcdesc.got = UCB_PR_GOT (ucbp);
	pr_result = ((personality_routine) &funcdesc)
	  (_US_UNWIND_FRAME_STARTING, ucbp, (_Unwind_Context *) vrs);
      }
#else
      pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
	(_US_UNWIND_FRAME_STARTING, ucbp, (_Unwind_Context *) vrs);
#endif
    }
  while (pr_result == _URC_CONTINUE_UNWIND);
  
  if (pr_result != _URC_INSTALL_CONTEXT)
    abort();

#if __FDPIC__
  /* r9 could have been lost due to PLT jump.  Restore correct value.  */
  vrs->core.r[FDPIC_REGNUM] = _Unwind_gnu_Find_got (VRS_PC (vrs));
#endif

  uw_restore_core_regs (vrs, &vrs->core);
}

/* Perform phase2 forced unwinding.  */

static _Unwind_Reason_Code
unwind_phase2_forced (_Unwind_Control_Block *ucbp, phase2_vrs *entry_vrs,
		      int resuming)
{
  _Unwind_Stop_Fn stop_fn = (_Unwind_Stop_Fn) UCB_FORCED_STOP_FN (ucbp);
  void *stop_arg = (void *)UCB_FORCED_STOP_ARG (ucbp);
  _Unwind_Reason_Code pr_result = 0;
  /* We use phase1_vrs here even though we do not demand save, for the
     prev_sp field.  */
  phase1_vrs saved_vrs, next_vrs;

  /* Save the core registers.  */
  saved_vrs.core = entry_vrs->core;
  /* We don't need to demand-save the non-core registers, because we
     unwind in a single pass.  */
  saved_vrs.demand_save_flags = 0;

  /* Unwind until we reach a propagation barrier.  */
  do
    {
      _Unwind_State action;
      _Unwind_Reason_Code entry_code;
      _Unwind_Reason_Code stop_code;

      /* Find the entry for this routine.  */
      entry_code = get_eit_entry (ucbp, VRS_PC (&saved_vrs));

      if (resuming)
	{
	  action = _US_UNWIND_FRAME_RESUME | _US_FORCE_UNWIND;
	  resuming = 0;
	}
      else
	action = _US_UNWIND_FRAME_STARTING | _US_FORCE_UNWIND;

      if (entry_code == _URC_OK)
	{
	  UCB_SAVED_CALLSITE_ADDR (ucbp) = VRS_PC (&saved_vrs);

	  next_vrs = saved_vrs;

	  /* Call the pr to decide what to do.  */
#if __FDPIC__
	  {
	    volatile struct funcdesc_t funcdesc;
	    funcdesc.ptr = UCB_PR_ADDR (ucbp);
	    funcdesc.got = UCB_PR_GOT (ucbp);
	    pr_result = ((personality_routine) &funcdesc)
	      (action, ucbp, (void *) &next_vrs);
	  }
#else
	  pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
	    (action, ucbp, (void *) &next_vrs);
#endif

	  saved_vrs.prev_sp = VRS_SP (&next_vrs);
	}
      else
	{
	  /* Treat any failure as the end of unwinding, to cope more
	     gracefully with missing EH information.  Mixed EH and
	     non-EH within one object will usually result in failure,
	     because the .ARM.exidx tables do not indicate the end
	     of the code to which they apply; but mixed EH and non-EH
	     shared objects should return an unwind failure at the
	     entry of a non-EH shared object.  */
	  action |= _US_END_OF_STACK;

	  saved_vrs.prev_sp = VRS_SP (&saved_vrs);
	}

      stop_code = stop_fn (1, action, ucbp->exception_class, ucbp,
			   (void *)&saved_vrs, stop_arg);
      if (stop_code != _URC_NO_REASON)
	return _URC_FAILURE;

      if (entry_code != _URC_OK)
	return entry_code;

      saved_vrs = next_vrs;
    }
  while (pr_result == _URC_CONTINUE_UNWIND);

  if (pr_result != _URC_INSTALL_CONTEXT)
    {
      /* Some sort of failure has occurred in the pr and probably the
	 pr returned _URC_FAILURE.  */
      return _URC_FAILURE;
    }

#if __FDPIC__
  /* r9 could have been lost due to PLT jump.  Restore correct value.  */
  saved_vrs.core.r[FDPIC_REGNUM] = _Unwind_gnu_Find_got (VRS_PC (&saved_vrs));
#endif

  uw_restore_core_regs (&saved_vrs, &saved_vrs.core);
}

/* This is a very limited implementation of _Unwind_GetCFA.  It returns
   the stack pointer as it is about to be unwound, and is only valid
   while calling the stop function during forced unwinding.  If the
   current personality routine result is going to run a cleanup, this
   will not be the CFA; but when the frame is really unwound, it will
   be.  */

_Unwind_Word
_Unwind_GetCFA (_Unwind_Context *context)
{
  return ((phase1_vrs *) context)->prev_sp;
}

/* Perform phase1 unwinding.  UCBP is the exception being thrown, and
   entry_VRS is the register state on entry to _Unwind_RaiseException.  */

_Unwind_Reason_Code
__gnu_Unwind_RaiseException (_Unwind_Control_Block *, phase2_vrs *);

_Unwind_Reason_Code
__gnu_Unwind_RaiseException (_Unwind_Control_Block * ucbp,
			     phase2_vrs * entry_vrs)
{
  phase1_vrs saved_vrs;
  _Unwind_Reason_Code pr_result;

  /* Set the pc to the call site.  */
  VRS_PC (entry_vrs) = VRS_RETURN(entry_vrs);

  /* Save the core registers.  */
  saved_vrs.core = entry_vrs->core;
  /* Set demand-save flags.  */
  saved_vrs.demand_save_flags = ~(_uw) 0;
  
  /* Unwind until we reach a propagation barrier.  */
  do
    {
      /* Find the entry for this routine.  */
      if (get_eit_entry (ucbp, VRS_PC (&saved_vrs)) != _URC_OK)
	return _URC_FAILURE;

      /* Call the pr to decide what to do.  */
#if __FDPIC__
      {
	volatile struct funcdesc_t funcdesc;
	funcdesc.ptr = UCB_PR_ADDR (ucbp);
	funcdesc.got = UCB_PR_GOT (ucbp);
	pr_result = ((personality_routine) &funcdesc)
	  (_US_VIRTUAL_UNWIND_FRAME, ucbp, (void *) &saved_vrs);
      }
#else
      pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
	(_US_VIRTUAL_UNWIND_FRAME, ucbp, (void *) &saved_vrs);
#endif
    }
  while (pr_result == _URC_CONTINUE_UNWIND);

  /* We've unwound as far as we want to go, so restore the original
     register state.  */
  restore_non_core_regs (&saved_vrs);
  if (pr_result != _URC_HANDLER_FOUND)
    {
      /* Some sort of failure has occurred in the pr and probably the
	 pr returned _URC_FAILURE.  */
      return _URC_FAILURE;
    }
  
  unwind_phase2 (ucbp, entry_vrs);
}

/* Resume unwinding after a cleanup has been run.  UCBP is the exception
   being thrown and ENTRY_VRS is the register state on entry to
   _Unwind_Resume.  */
_Unwind_Reason_Code
__gnu_Unwind_ForcedUnwind (_Unwind_Control_Block *,
			   _Unwind_Stop_Fn, void *, phase2_vrs *);

_Unwind_Reason_Code
__gnu_Unwind_ForcedUnwind (_Unwind_Control_Block *ucbp,
			   _Unwind_Stop_Fn stop_fn, void *stop_arg,
			   phase2_vrs *entry_vrs)
{
  UCB_FORCED_STOP_FN (ucbp) = (_uw) stop_fn;
  UCB_FORCED_STOP_ARG (ucbp) = (_uw) stop_arg;

  /* Set the pc to the call site.  */
  VRS_PC (entry_vrs) = VRS_RETURN(entry_vrs);

  return unwind_phase2_forced (ucbp, entry_vrs, 0);
}

_Unwind_Reason_Code
__gnu_Unwind_Resume (_Unwind_Control_Block *, phase2_vrs *);

_Unwind_Reason_Code
__gnu_Unwind_Resume (_Unwind_Control_Block * ucbp, phase2_vrs * entry_vrs)
{
  _Unwind_Reason_Code pr_result;

  /* Recover the saved address.  */
  VRS_PC (entry_vrs) = UCB_SAVED_CALLSITE_ADDR (ucbp);

  if (UCB_FORCED_STOP_FN (ucbp))
    {
      unwind_phase2_forced (ucbp, entry_vrs, 1);

      /* We can't return failure at this point.  */
      abort ();
    }

  /* Call the cached PR.  */
#if __FDPIC__
  {
    volatile struct funcdesc_t funcdesc;
    funcdesc.ptr = UCB_PR_ADDR (ucbp);
    funcdesc.got = UCB_PR_GOT (ucbp);
    pr_result = ((personality_routine) &funcdesc)
      (_US_UNWIND_FRAME_RESUME, ucbp, (_Unwind_Context *) entry_vrs);
  }
#else
  pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
	(_US_UNWIND_FRAME_RESUME, ucbp, (_Unwind_Context *) entry_vrs);
#endif

  switch (pr_result)
    {
    case _URC_INSTALL_CONTEXT:
      /* Upload the registers to enter the landing pad.  */
#if __FDPIC__
      /* r9 could have been lost due to PLT jump.  Restore correct value.  */
      entry_vrs->core.r[FDPIC_REGNUM] = _Unwind_gnu_Find_got (VRS_PC (entry_vrs));
#endif
      uw_restore_core_regs (entry_vrs, &entry_vrs->core);

    case _URC_CONTINUE_UNWIND:
      /* Continue unwinding the next frame.  */
      unwind_phase2 (ucbp, entry_vrs);

    default:
      abort ();
    }
}

_Unwind_Reason_Code
__gnu_Unwind_Resume_or_Rethrow (_Unwind_Control_Block *, phase2_vrs *);

_Unwind_Reason_Code
__gnu_Unwind_Resume_or_Rethrow (_Unwind_Control_Block * ucbp,
				phase2_vrs * entry_vrs)
{
  if (!UCB_FORCED_STOP_FN (ucbp))
    return __gnu_Unwind_RaiseException (ucbp, entry_vrs);

  /* Set the pc to the call site.  */
  VRS_PC (entry_vrs) = VRS_RETURN (entry_vrs);
  /* Continue unwinding the next frame.  */
  return unwind_phase2_forced (ucbp, entry_vrs, 0);
}

/* Clean up an exception object when unwinding is complete.  */
void
_Unwind_Complete (_Unwind_Control_Block * ucbp __attribute__((unused)))
{
}


/* Free an exception.  */

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


/* Perform stack backtrace through unwind data.  */
_Unwind_Reason_Code
__gnu_Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument,
		       phase2_vrs * entry_vrs);
_Unwind_Reason_Code
__gnu_Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument,
		       phase2_vrs * entry_vrs)
{
  phase1_vrs saved_vrs;
  _Unwind_Reason_Code code;

  _Unwind_Control_Block ucb;
  _Unwind_Control_Block *ucbp = &ucb;

  /* Set the pc to the call site.  */
  VRS_PC (entry_vrs) = VRS_RETURN (entry_vrs);

  /* Save the core registers.  */
  saved_vrs.core = entry_vrs->core;
  /* Set demand-save flags.  */
  saved_vrs.demand_save_flags = ~(_uw) 0;
  
  do
    {
      /* Find the entry for this routine.  */
      if (get_eit_entry (ucbp, VRS_PC (&saved_vrs)) != _URC_OK)
	{
	  code = _URC_FAILURE;
	  break;
	}

      /* The dwarf unwinder assumes the context structure holds things
	 like the function and LSDA pointers.  The ARM implementation
	 caches these in the exception header (UCB).  To avoid
	 rewriting everything we make the virtual IP register point at
	 the UCB.  */
      _Unwind_SetGR((_Unwind_Context *)&saved_vrs, UNWIND_POINTER_REG, (_Unwind_Ptr) ucbp);

      /* Call trace function.  */
      if ((*trace) ((_Unwind_Context *) &saved_vrs, trace_argument) 
	  != _URC_NO_REASON)
	{
	  code = _URC_FAILURE;
	  break;
	}

      /* Call the pr to decide what to do.  */
#if __FDPIC__
      {
	volatile struct funcdesc_t funcdesc;
	funcdesc.ptr = UCB_PR_ADDR (ucbp);
	funcdesc.got = UCB_PR_GOT (ucbp);
	code = ((personality_routine) &funcdesc)
	  (_US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND,
	   ucbp, (void *) &saved_vrs);
      }
#else
      code = ((personality_routine) UCB_PR_ADDR (ucbp))
	(_US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND, 
	 ucbp, (void *) &saved_vrs);
#endif
    }
  while (code != _URC_END_OF_STACK
	 && code != _URC_FAILURE);

  restore_non_core_regs (&saved_vrs);
  return code;
}


/* Common implementation for ARM ABI defined personality routines.
   ID is the index of the personality routine, other arguments are as defined
   by __aeabi_unwind_cpp_pr{0,1,2}.  */

static _Unwind_Reason_Code
__gnu_unwind_pr_common (_Unwind_State state,
			_Unwind_Control_Block *ucbp,
			_Unwind_Context *context,
			int id)
{
  __gnu_unwind_state uws;
  _uw *data;
  _uw offset;
  _uw len;
  _uw rtti_count;
  int phase2_call_unexpected_after_unwind = 0;
  int in_range = 0;
  int forced_unwind = state & _US_FORCE_UNWIND;

  state &= _US_ACTION_MASK;

  data = (_uw *) ucbp->pr_cache.ehtp;
  uws.data = *(data++);
  uws.next = data;
  if (id == 0)
    {
      uws.data <<= 8;
      uws.words_left = 0;
      uws.bytes_left = 3;
    }
  else if (id < 3)
    {
      uws.words_left = (uws.data >> 16) & 0xff;
      uws.data <<= 16;
      uws.bytes_left = 2;
      data += uws.words_left;
    }

  /* Restore the saved pointer.  */
  if (state == _US_UNWIND_FRAME_RESUME)
    data = (_uw *) ucbp->cleanup_cache.bitpattern[0];

  if ((ucbp->pr_cache.additional & 1) == 0)
    {
      /* Process descriptors.  */
      while (*data)
	{
	  _uw addr;
	  _uw fnstart;

	  if (id == 2)
	    {
	      len = ((EHT32 *) data)->length;
	      offset = ((EHT32 *) data)->offset;
	      data += 2;
	    }
	  else
	    {
	      len = ((EHT16 *) data)->length;
	      offset = ((EHT16 *) data)->offset;
	      data++;
	    }

	  fnstart = ucbp->pr_cache.fnstart + (offset & ~1);
	  addr = _Unwind_GetGR (context, R_PC);
	  in_range = (fnstart <= addr && addr < fnstart + (len & ~1));

	  switch (((offset & 1) << 1) | (len & 1))
	    {
	    case 0:
	      /* Cleanup.  */
	      if (state != _US_VIRTUAL_UNWIND_FRAME
		  && in_range)
		{
		  /* Cleanup in range, and we are running cleanups.  */
		  _uw lp;

		  /* Landing pad address is 31-bit pc-relative offset.  */
		  lp = selfrel_offset31 (data);
		  data++;
		  /* Save the exception data pointer.  */
		  ucbp->cleanup_cache.bitpattern[0] = (_uw) data;
		  if (!__cxa_begin_cleanup (ucbp))
		    return _URC_FAILURE;
		  /* Setup the VRS to enter the landing pad.  */
		  _Unwind_SetGR (context, R_PC, lp);
		  return _URC_INSTALL_CONTEXT;
		}
	      /* Cleanup not in range, or we are in stage 1.  */
	      data++;
	      break;

	    case 1:
	      /* Catch handler.  */
	      if (state == _US_VIRTUAL_UNWIND_FRAME)
		{
		  if (in_range)
		    {
		      /* Check for a barrier.  */
		      _uw rtti;
		      bool is_reference = (data[0] & uint32_highbit) != 0;
		      void *matched;
		      enum __cxa_type_match_result match_type;

		      /* Check for no-throw areas.  */
		      if (data[1] == (_uw) -2)
			return _URC_FAILURE;

		      /* The thrown object immediately follows the ECB.  */
		      matched = (void *)(ucbp + 1);
		      if (data[1] != (_uw) -1)
			{
			  /* Match a catch specification.  */
			  rtti = _Unwind_decode_typeinfo_ptr (0,
							      (_uw) &data[1]);
			  match_type = __cxa_type_match (ucbp,
							 (type_info *) rtti,
							 is_reference,
							 &matched);
			}
		      else
			match_type = ctm_succeeded;

		      if (match_type)
			{
			  ucbp->barrier_cache.sp =
			    _Unwind_GetGR (context, R_SP);
			  // ctm_succeeded_with_ptr_to_base really
			  // means _c_t_m indirected the pointer
			  // object.  We have to reconstruct the
			  // additional pointer layer by using a temporary.
			  if (match_type == ctm_succeeded_with_ptr_to_base)
			    {
			      ucbp->barrier_cache.bitpattern[2]
				= (_uw) matched;
			      ucbp->barrier_cache.bitpattern[0]
				= (_uw) &ucbp->barrier_cache.bitpattern[2];
			    }
			  else
			    ucbp->barrier_cache.bitpattern[0] = (_uw) matched;
			  ucbp->barrier_cache.bitpattern[1] = (_uw) data;
			  return _URC_HANDLER_FOUND;
			}
		    }
		  /* Handler out of range, or not matched.  */
		}
	      else if (ucbp->barrier_cache.sp == _Unwind_GetGR (context, R_SP)
		       && ucbp->barrier_cache.bitpattern[1] == (_uw) data)
		{
		  /* Matched a previous propagation barrier.  */
		  _uw lp;

		  /* Setup for entry to the handler.  */
		  lp = selfrel_offset31 (data);
		  _Unwind_SetGR (context, R_PC, lp);
		  _Unwind_SetGR (context, 0, (_uw) ucbp);
		  return _URC_INSTALL_CONTEXT;
		}
	      /* Catch handler not matched.  Advance to the next descriptor.  */
	      data += 2;
	      break;

	    case 2:
	      rtti_count = data[0] & 0x7fffffff;
	      /* Exception specification.  */
	      if (state == _US_VIRTUAL_UNWIND_FRAME)
		{
		  if (in_range && (!forced_unwind || !rtti_count))
		    {
		      /* Match against the exception specification.  */
		      _uw i;
		      _uw rtti;
		      void *matched;

		      for (i = 0; i < rtti_count; i++)
			{
			  matched = (void *)(ucbp + 1);
			  rtti = _Unwind_decode_typeinfo_ptr (0,
			      (_uw) &data[i + 1]);
			  if (__cxa_type_match (ucbp, (type_info *) rtti, 0,
						&matched))
			    break;
			}

		      if (i == rtti_count)
			{
			  /* Exception does not match the spec.  */
			  ucbp->barrier_cache.sp =
			    _Unwind_GetGR (context, R_SP);
			  ucbp->barrier_cache.bitpattern[0] = (_uw) matched;
			  ucbp->barrier_cache.bitpattern[1] = (_uw) data;
			  return _URC_HANDLER_FOUND;
			}
		    }
		  /* Handler out of range, or exception is permitted.  */
		}
	      else if (ucbp->barrier_cache.sp == _Unwind_GetGR (context, R_SP)
		       && ucbp->barrier_cache.bitpattern[1] == (_uw) data)
		{
		  /* Matched a previous propagation barrier.  */
		  _uw lp;
		  /* Record the RTTI list for __cxa_call_unexpected.  */
		  ucbp->barrier_cache.bitpattern[1] = rtti_count;
		  ucbp->barrier_cache.bitpattern[2] = 0;
		  ucbp->barrier_cache.bitpattern[3] = 4;
		  ucbp->barrier_cache.bitpattern[4] = (_uw) &data[1];

		  if (data[0] & uint32_highbit)
		    {
		      data += rtti_count + 1;
		      /* Setup for entry to the handler.  */
		      lp = selfrel_offset31 (data);
		      data++;
		      _Unwind_SetGR (context, R_PC, lp);
		      _Unwind_SetGR (context, 0, (_uw) ucbp);
		      return _URC_INSTALL_CONTEXT;
		    }
		  else
		    phase2_call_unexpected_after_unwind = 1;
		}
	      if (data[0] & uint32_highbit)
		data++;
	      data += rtti_count + 1;
	      break;

	    default:
	      /* Should never happen.  */
	      return _URC_FAILURE;
	    }
	  /* Finished processing this descriptor.  */
	}
    }

  if (id >= 3)
    {
      /* 24-bit ecoding */
      if (__gnu_unwind_24bit (context, uws.data, id == 4) != _URC_OK)
	return _URC_FAILURE;
    }
  else
    {
      if (__gnu_unwind_execute (context, &uws) != _URC_OK)
	return _URC_FAILURE;
    }
    
  if (phase2_call_unexpected_after_unwind)
    {
      /* Enter __cxa_unexpected as if called from the call site.  */
      _Unwind_SetGR (context, R_LR, _Unwind_GetGR (context, R_PC));
      _Unwind_SetGR (context, R_PC, (_uw) &__cxa_call_unexpected);
      return _URC_INSTALL_CONTEXT;
    }

  return _URC_CONTINUE_UNWIND;
}
