/* Common unwinding code for ARM EABI and C6X.
   Copyright (C) 2004-2021 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, 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;
}
