Home | History | Annotate | Line # | Download | only in libgcc
      1   1.1  mrg /* Common unwinding code for ARM EABI and C6X.
      2  1.10  mrg    Copyright (C) 2004-2022 Free Software Foundation, Inc.
      3   1.1  mrg    Contributed by Paul Brook
      4   1.1  mrg 
      5   1.1  mrg    This file is free software; you can redistribute it and/or modify it
      6   1.1  mrg    under the terms of the GNU General Public License as published by the
      7   1.1  mrg    Free Software Foundation; either version 3, or (at your option) any
      8   1.1  mrg    later version.
      9   1.1  mrg 
     10   1.1  mrg    This file is distributed in the hope that it will be useful, but
     11   1.1  mrg    WITHOUT ANY WARRANTY; without even the implied warranty of
     12   1.1  mrg    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13   1.1  mrg    General Public License for more details.
     14   1.1  mrg 
     15   1.1  mrg    Under Section 7 of GPL version 3, you are granted additional
     16   1.1  mrg    permissions described in the GCC Runtime Library Exception, version
     17   1.1  mrg    3.1, as published by the Free Software Foundation.
     18   1.1  mrg 
     19   1.1  mrg    You should have received a copy of the GNU General Public License and
     20   1.1  mrg    a copy of the GCC Runtime Library Exception along with this program;
     21   1.1  mrg    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     22   1.1  mrg    <http://www.gnu.org/licenses/>.  */
     23   1.1  mrg 
     24   1.1  mrg #include "tconfig.h"
     25   1.1  mrg #include "tsystem.h"
     26   1.1  mrg #include "unwind.h"
     27   1.1  mrg 
     28   1.1  mrg /* Used for SystemTap unwinder probe.  */
     29   1.1  mrg #ifdef HAVE_SYS_SDT_H
     30   1.1  mrg #include <sys/sdt.h>
     31   1.1  mrg #endif
     32   1.1  mrg 
     33   1.9  mrg #if __FDPIC__
     34   1.9  mrg /* Load r7 with rt_sigreturn value.  */
     35   1.9  mrg #define ARM_SET_R7_RT_SIGRETURN		0xe3a070ad	/* mov   r7, #0xad */
     36   1.9  mrg #define THUMB2_SET_R7_RT_SIGRETURN	0x07adf04f	/* mov.w r7, #0xad */
     37   1.9  mrg 
     38   1.9  mrg /* FDPIC jump to restorer sequence.  */
     39   1.9  mrg #define FDPIC_LDR_R12_WITH_FUNCDESC	0xe59fc004	/* ldr   r12, [pc, #4] */
     40   1.9  mrg #define FDPIC_LDR_R9_WITH_GOT		0xe59c9004	/* ldr   r9, [r12, #4] */
     41   1.9  mrg #define FDPIC_LDR_PC_WITH_RESTORER	0xe59cf000	/* ldr   pc, [r12] */
     42   1.9  mrg #define FDPIC_T2_LDR_R12_WITH_FUNCDESC  0xc008f8df	/* ldr.w r12, [pc, #8] */
     43   1.9  mrg #define FDPIC_T2_LDR_R9_WITH_GOT	0x9004f8dc	/* ldr.w r9, [r12, #4] */
     44   1.9  mrg #define FDPIC_T2_LDR_PC_WITH_RESTORER   0xf000f8dc	/* ldr.w pc, [r12] */
     45   1.9  mrg #define FDPIC_FUNCDESC_OFFSET		12
     46   1.9  mrg 
     47   1.9  mrg /* Signal frame offsets.  */
     48   1.9  mrg #define ARM_NEW_RT_SIGFRAME_UCONTEXT	0x80
     49   1.9  mrg #define ARM_UCONTEXT_SIGCONTEXT		0x14
     50   1.9  mrg #define ARM_SIGCONTEXT_R0		0xc
     51   1.9  mrg #endif
     52   1.9  mrg 
     53   1.1  mrg /* Definitions for C++ runtime support routines.  We make these weak
     54   1.1  mrg    declarations to avoid pulling in libsupc++ unnecessarily.  */
     55   1.1  mrg typedef unsigned char bool;
     56   1.1  mrg 
     57   1.1  mrg typedef struct _ZSt9type_info type_info; /* This names C++ type_info type */
     58   1.1  mrg enum __cxa_type_match_result
     59   1.1  mrg   {
     60   1.1  mrg     ctm_failed = 0,
     61   1.1  mrg     ctm_succeeded = 1,
     62   1.1  mrg     ctm_succeeded_with_ptr_to_base = 2
     63   1.1  mrg   };
     64   1.1  mrg 
     65   1.1  mrg void __attribute__((weak)) __cxa_call_unexpected(_Unwind_Control_Block *ucbp);
     66   1.1  mrg bool __attribute__((weak)) __cxa_begin_cleanup(_Unwind_Control_Block *ucbp);
     67   1.1  mrg enum __cxa_type_match_result __attribute__((weak)) __cxa_type_match
     68   1.1  mrg   (_Unwind_Control_Block *ucbp, const type_info *rttip,
     69   1.1  mrg    bool is_reference, void **matched_object);
     70   1.1  mrg 
     71   1.1  mrg _Unwind_Ptr __attribute__((weak))
     72   1.1  mrg __gnu_Unwind_Find_exidx (_Unwind_Ptr, int *);
     73   1.1  mrg 
     74   1.1  mrg #define EXIDX_CANTUNWIND 1
     75   1.1  mrg #define uint32_highbit (((_uw) 1) << 31)
     76   1.1  mrg 
     77   1.1  mrg #define UCB_FORCED_STOP_FN(ucbp) ((ucbp)->unwinder_cache.reserved1)
     78   1.1  mrg #define UCB_PR_ADDR(ucbp) ((ucbp)->unwinder_cache.reserved2)
     79   1.1  mrg #define UCB_SAVED_CALLSITE_ADDR(ucbp) ((ucbp)->unwinder_cache.reserved3)
     80   1.1  mrg #define UCB_FORCED_STOP_ARG(ucbp) ((ucbp)->unwinder_cache.reserved4)
     81   1.9  mrg #define UCB_PR_GOT(ucbp) ((ucbp)->unwinder_cache.reserved5)
     82   1.1  mrg 
     83   1.1  mrg /* Unwind descriptors.  */
     84   1.1  mrg 
     85   1.1  mrg typedef struct
     86   1.1  mrg {
     87   1.1  mrg   _uw16 length;
     88   1.1  mrg   _uw16 offset;
     89   1.1  mrg } EHT16;
     90   1.1  mrg 
     91   1.1  mrg typedef struct
     92   1.1  mrg {
     93   1.1  mrg   _uw length;
     94   1.1  mrg   _uw offset;
     95   1.1  mrg } EHT32;
     96   1.1  mrg 
     97   1.1  mrg /* An exception index table entry.  */
     98   1.1  mrg 
     99   1.1  mrg typedef struct __EIT_entry
    100   1.1  mrg {
    101   1.1  mrg   _uw fnoffset;
    102   1.1  mrg   _uw content;
    103   1.1  mrg } __EIT_entry;
    104   1.1  mrg 
    105   1.9  mrg #ifdef __FDPIC__
    106   1.9  mrg 
    107   1.9  mrg /* Only used in FDPIC case.  */
    108   1.9  mrg struct funcdesc_t
    109   1.9  mrg {
    110   1.9  mrg   unsigned int ptr;
    111   1.9  mrg   unsigned int got;
    112   1.9  mrg };
    113   1.9  mrg #endif
    114   1.9  mrg 
    115   1.1  mrg /* Assembly helper functions.  */
    116   1.1  mrg 
    117   1.1  mrg /* Restore core register state.  Never returns.  */
    118   1.1  mrg void __attribute__((noreturn)) restore_core_regs (struct core_regs *);
    119   1.1  mrg 
    120   1.1  mrg 
    121   1.1  mrg /* Restore coprocessor state after phase1 unwinding.  */
    122   1.1  mrg static void restore_non_core_regs (phase1_vrs * vrs);
    123   1.1  mrg 
    124   1.1  mrg /* A better way to do this would probably be to compare the absolute address
    125   1.1  mrg    with a segment relative relocation of the same symbol.  */
    126   1.1  mrg 
    127   1.1  mrg extern int __text_start;
    128   1.1  mrg extern int __data_start;
    129   1.1  mrg 
    130   1.1  mrg /* The exception index table location.  */
    131   1.1  mrg extern __EIT_entry __exidx_start;
    132   1.1  mrg extern __EIT_entry __exidx_end;
    133   1.1  mrg 
    134   1.1  mrg /* Core unwinding functions.  */
    135   1.1  mrg 
    136   1.1  mrg /* Calculate the address encoded by a 31-bit self-relative offset at address
    137   1.1  mrg    P.  */
    138   1.1  mrg static inline _uw selfrel_offset31 (const _uw *p);
    139   1.1  mrg 
    140   1.1  mrg static _uw __gnu_unwind_get_pr_addr (int idx);
    141   1.1  mrg 
    142   1.1  mrg static void _Unwind_DebugHook (void *, void *)
    143   1.1  mrg   __attribute__ ((__noinline__, __used__, __noclone__));
    144   1.1  mrg 
    145   1.1  mrg /* This function is called during unwinding.  It is intended as a hook
    146   1.1  mrg    for a debugger to intercept exceptions.  CFA is the CFA of the
    147   1.1  mrg    target frame.  HANDLER is the PC to which control will be
    148   1.1  mrg    transferred.  */
    149   1.1  mrg 
    150   1.1  mrg static void
    151   1.1  mrg _Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
    152   1.1  mrg 		   void *handler __attribute__ ((__unused__)))
    153   1.1  mrg {
    154   1.1  mrg   /* We only want to use stap probes starting with v3.  Earlier
    155   1.1  mrg      versions added too much startup cost.  */
    156   1.1  mrg #if defined (HAVE_SYS_SDT_H) && defined (STAP_PROBE2) && _SDT_NOTE_TYPE >= 3
    157   1.1  mrg   STAP_PROBE2 (libgcc, unwind, cfa, handler);
    158   1.1  mrg #else
    159   1.1  mrg   asm ("");
    160   1.1  mrg #endif
    161   1.1  mrg }
    162   1.1  mrg 
    163   1.1  mrg /* This is a wrapper to be called when we need to restore core registers.
    164   1.1  mrg    It will call `_Unwind_DebugHook' before restoring the registers, thus
    165   1.1  mrg    making it possible to intercept and debug exceptions.
    166   1.1  mrg 
    167   1.1  mrg    When calling `_Unwind_DebugHook', the first argument (the CFA) is zero
    168   1.1  mrg    because we are not interested in it.  However, it must be there (even
    169   1.1  mrg    being zero) because GDB expects to find it when using the probe.  */
    170   1.1  mrg 
    171   1.1  mrg #define uw_restore_core_regs(TARGET, CORE)				      \
    172   1.1  mrg   do									      \
    173   1.1  mrg     {									      \
    174   1.1  mrg       void *handler = __builtin_frob_return_addr ((void *) VRS_PC (TARGET));  \
    175   1.1  mrg       _Unwind_DebugHook (0, handler);					      \
    176   1.1  mrg       restore_core_regs (CORE);						      \
    177   1.1  mrg     }									      \
    178   1.1  mrg   while (0)
    179   1.1  mrg 
    180   1.1  mrg /* Perform a binary search for RETURN_ADDRESS in TABLE.  The table contains
    181   1.1  mrg    NREC entries.  */
    182   1.1  mrg 
    183   1.1  mrg static const __EIT_entry *
    184   1.1  mrg search_EIT_table (const __EIT_entry * table, int nrec, _uw return_address)
    185   1.1  mrg {
    186   1.1  mrg   _uw next_fn;
    187   1.1  mrg   _uw this_fn;
    188   1.1  mrg   int n, left, right;
    189   1.1  mrg 
    190   1.1  mrg   if (nrec == 0)
    191   1.1  mrg     return (__EIT_entry *) 0;
    192   1.1  mrg 
    193   1.1  mrg   left = 0;
    194   1.1  mrg   right = nrec - 1;
    195   1.1  mrg 
    196   1.1  mrg   while (1)
    197   1.1  mrg     {
    198   1.1  mrg       n = (left + right) / 2;
    199   1.1  mrg       this_fn = selfrel_offset31 (&table[n].fnoffset);
    200   1.1  mrg       if (n != nrec - 1)
    201   1.1  mrg 	next_fn = selfrel_offset31 (&table[n + 1].fnoffset) - 1;
    202   1.1  mrg       else
    203   1.1  mrg 	next_fn = (_uw)0 - 1;
    204   1.1  mrg 
    205   1.1  mrg       if (return_address < this_fn)
    206   1.1  mrg 	{
    207   1.1  mrg 	  if (n == left)
    208   1.1  mrg 	    return (__EIT_entry *) 0;
    209   1.1  mrg 	  right = n - 1;
    210   1.1  mrg 	}
    211   1.1  mrg       else if (return_address <= next_fn)
    212   1.1  mrg 	return &table[n];
    213   1.1  mrg       else
    214   1.1  mrg 	left = n + 1;
    215   1.1  mrg     }
    216   1.1  mrg }
    217   1.1  mrg 
    218   1.9  mrg #if __FDPIC__
    219   1.9  mrg /* VFP is not restored, but this is sufficient to allow unwinding.  */
    220   1.9  mrg static _Unwind_Reason_Code
    221   1.9  mrg __gnu_personality_sigframe_fdpic (_Unwind_State state,
    222   1.9  mrg 				  _Unwind_Control_Block *ucbp,
    223   1.9  mrg 				  _Unwind_Context *context)
    224   1.9  mrg {
    225   1.9  mrg     unsigned int sp;
    226   1.9  mrg     unsigned int pc;
    227   1.9  mrg     unsigned int funcdesc;
    228   1.9  mrg     unsigned int handler;
    229   1.9  mrg     unsigned int first_handler_instruction;
    230   1.9  mrg     int i;
    231   1.9  mrg 
    232   1.9  mrg     _Unwind_VRS_Get (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, &sp);
    233   1.9  mrg     _Unwind_VRS_Get (context, _UVRSC_CORE, R_PC, _UVRSD_UINT32, &pc);
    234   1.9  mrg 
    235   1.9  mrg     funcdesc = *(unsigned int *)((pc & ~1) + FDPIC_FUNCDESC_OFFSET);
    236   1.9  mrg     handler = *(unsigned int *)(funcdesc);
    237   1.9  mrg     first_handler_instruction = *(unsigned int *)(handler & ~1);
    238   1.9  mrg 
    239   1.9  mrg     /* Adjust SP to point to the start of registers according to
    240   1.9  mrg        signal type.  */
    241   1.9  mrg     if (first_handler_instruction == ARM_SET_R7_RT_SIGRETURN
    242   1.9  mrg 	|| first_handler_instruction == THUMB2_SET_R7_RT_SIGRETURN)
    243   1.9  mrg 	sp += ARM_NEW_RT_SIGFRAME_UCONTEXT
    244   1.9  mrg 	  + ARM_UCONTEXT_SIGCONTEXT
    245   1.9  mrg 	  + ARM_SIGCONTEXT_R0;
    246   1.9  mrg     else
    247   1.9  mrg 	sp += ARM_UCONTEXT_SIGCONTEXT
    248   1.9  mrg 	  + ARM_SIGCONTEXT_R0;
    249   1.9  mrg     /* Restore regs saved on stack by the kernel.  */
    250   1.9  mrg     for (i = 0; i < 16; i++)
    251   1.9  mrg 	_Unwind_VRS_Set (context, _UVRSC_CORE, i, _UVRSD_UINT32, sp + 4 * i);
    252   1.9  mrg 
    253   1.9  mrg     return _URC_CONTINUE_UNWIND;
    254   1.9  mrg }
    255   1.9  mrg #endif
    256   1.9  mrg 
    257   1.1  mrg /* Find the exception index table eintry for the given address.
    258   1.1  mrg    Fill in the relevant fields of the UCB.
    259   1.1  mrg    Returns _URC_FAILURE if an error occurred, _URC_OK on success.  */
    260   1.1  mrg 
    261   1.1  mrg static _Unwind_Reason_Code
    262   1.1  mrg get_eit_entry (_Unwind_Control_Block *ucbp, _uw return_address)
    263   1.1  mrg {
    264   1.1  mrg   const __EIT_entry * eitp;
    265   1.1  mrg   int nrec;
    266   1.1  mrg 
    267   1.1  mrg   /* The return address is the address of the instruction following the
    268   1.1  mrg      call instruction (plus one in thumb mode).  If this was the last
    269   1.1  mrg      instruction in the function the address will lie in the following
    270   1.1  mrg      function.  Subtract 2 from the address so that it points within the call
    271   1.1  mrg      instruction itself.  */
    272   1.1  mrg   return_address -= 2;
    273   1.1  mrg 
    274   1.1  mrg   if (__gnu_Unwind_Find_exidx)
    275   1.1  mrg     {
    276   1.1  mrg       eitp = (const __EIT_entry *) __gnu_Unwind_Find_exidx (return_address,
    277   1.1  mrg 							    &nrec);
    278   1.1  mrg       if (!eitp)
    279   1.1  mrg 	{
    280   1.9  mrg #if __FDPIC__
    281   1.9  mrg 	  /* If we are unwinding a signal handler then perhaps we have
    282   1.9  mrg 	     reached a trampoline.  Try to detect jump to restorer
    283   1.9  mrg 	     sequence.  */
    284   1.9  mrg 	  _uw *pc = (_uw *)((return_address+2) & ~1);
    285   1.9  mrg 	  if ((pc[0] == FDPIC_LDR_R12_WITH_FUNCDESC
    286   1.9  mrg 	       && pc[1] == FDPIC_LDR_R9_WITH_GOT
    287   1.9  mrg 	       && pc[2] == FDPIC_LDR_PC_WITH_RESTORER)
    288   1.9  mrg 	      || (pc[0] == FDPIC_T2_LDR_R12_WITH_FUNCDESC
    289   1.9  mrg 		  && pc[1] == FDPIC_T2_LDR_R9_WITH_GOT
    290   1.9  mrg 		  && pc[2] == FDPIC_T2_LDR_PC_WITH_RESTORER))
    291   1.9  mrg 	    {
    292   1.9  mrg 	      struct funcdesc_t *funcdesc
    293   1.9  mrg 		= (struct funcdesc_t *) &__gnu_personality_sigframe_fdpic;
    294   1.9  mrg 
    295   1.9  mrg 	      UCB_PR_ADDR (ucbp) = funcdesc->ptr;
    296   1.9  mrg 	      UCB_PR_GOT (ucbp) = funcdesc->got;
    297   1.9  mrg 
    298   1.9  mrg 	      return _URC_OK;
    299   1.9  mrg 	    }
    300   1.9  mrg #endif
    301   1.1  mrg 	  UCB_PR_ADDR (ucbp) = 0;
    302   1.1  mrg 	  return _URC_FAILURE;
    303   1.1  mrg 	}
    304   1.1  mrg     }
    305   1.1  mrg   else
    306   1.1  mrg     {
    307   1.1  mrg       eitp = &__exidx_start;
    308   1.1  mrg       nrec = &__exidx_end - &__exidx_start;
    309   1.1  mrg     }
    310   1.1  mrg 
    311   1.1  mrg   eitp = search_EIT_table (eitp, nrec, return_address);
    312   1.1  mrg 
    313   1.1  mrg   if (!eitp)
    314   1.1  mrg     {
    315   1.9  mrg #if __FDPIC__
    316   1.9  mrg       /* If we are unwinding a signal handler then perhaps we have
    317   1.9  mrg 	 reached a trampoline.  Try to detect jump to restorer
    318   1.9  mrg 	 sequence.  */
    319   1.9  mrg       _uw *pc = (_uw *)((return_address+2) & ~1);
    320   1.9  mrg       if ((pc[0] == FDPIC_LDR_R12_WITH_FUNCDESC
    321   1.9  mrg 	   && pc[1] == FDPIC_LDR_R9_WITH_GOT
    322   1.9  mrg 	   && pc[2] == FDPIC_LDR_PC_WITH_RESTORER)
    323   1.9  mrg 	  || (pc[0] == FDPIC_T2_LDR_R12_WITH_FUNCDESC
    324   1.9  mrg 	      && pc[1] == FDPIC_T2_LDR_R9_WITH_GOT
    325   1.9  mrg 	      && pc[2] == FDPIC_T2_LDR_PC_WITH_RESTORER))
    326   1.9  mrg 	{
    327   1.9  mrg 	  struct funcdesc_t *funcdesc
    328   1.9  mrg 	    = (struct funcdesc_t *) &__gnu_personality_sigframe_fdpic;
    329   1.9  mrg 
    330   1.9  mrg 	  UCB_PR_ADDR (ucbp) = funcdesc->ptr;
    331   1.9  mrg 	  UCB_PR_GOT (ucbp) = funcdesc->got;
    332   1.9  mrg 
    333   1.9  mrg 	  return _URC_OK;
    334   1.9  mrg 	}
    335   1.9  mrg #endif
    336   1.1  mrg       UCB_PR_ADDR (ucbp) = 0;
    337   1.1  mrg       return _URC_FAILURE;
    338   1.1  mrg     }
    339   1.1  mrg   ucbp->pr_cache.fnstart = selfrel_offset31 (&eitp->fnoffset);
    340   1.1  mrg 
    341   1.1  mrg   /* Can this frame be unwound at all?  */
    342   1.1  mrg   if (eitp->content == EXIDX_CANTUNWIND)
    343   1.1  mrg     {
    344   1.9  mrg #if __FDPIC__
    345   1.9  mrg       /* If we are unwinding a signal handler then perhaps we have
    346   1.9  mrg 	 reached a trampoline.  Try to detect jump to restorer
    347   1.9  mrg 	 sequence.  */
    348   1.9  mrg       _uw *pc = (_uw *)((return_address+2) & ~1);
    349   1.9  mrg       if ((pc[0] == FDPIC_LDR_R12_WITH_FUNCDESC
    350   1.9  mrg 	   && pc[1] == FDPIC_LDR_R9_WITH_GOT
    351   1.9  mrg 	   && pc[2] == FDPIC_LDR_PC_WITH_RESTORER)
    352   1.9  mrg 	  || (pc[0] == FDPIC_T2_LDR_R12_WITH_FUNCDESC
    353   1.9  mrg 	      && pc[1] == FDPIC_T2_LDR_R9_WITH_GOT
    354   1.9  mrg 	      && pc[2] == FDPIC_T2_LDR_PC_WITH_RESTORER))
    355   1.9  mrg 	{
    356   1.9  mrg 	  struct funcdesc_t *funcdesc
    357   1.9  mrg 	    = (struct funcdesc_t *) &__gnu_personality_sigframe_fdpic;
    358   1.9  mrg 
    359   1.9  mrg 	  UCB_PR_ADDR (ucbp) = funcdesc->ptr;
    360   1.9  mrg 	  UCB_PR_GOT (ucbp) = funcdesc->got;
    361   1.9  mrg 
    362   1.9  mrg 	  return _URC_OK;
    363   1.9  mrg 	}
    364   1.9  mrg #endif
    365   1.1  mrg       UCB_PR_ADDR (ucbp) = 0;
    366   1.1  mrg       return _URC_END_OF_STACK;
    367   1.1  mrg     }
    368   1.1  mrg 
    369   1.1  mrg   /* Obtain the address of the "real" __EHT_Header word.  */
    370   1.1  mrg 
    371   1.1  mrg   if (eitp->content & uint32_highbit)
    372   1.1  mrg     {
    373   1.1  mrg       /* It is immediate data.  */
    374   1.1  mrg       ucbp->pr_cache.ehtp = (_Unwind_EHT_Header *)&eitp->content;
    375   1.1  mrg       ucbp->pr_cache.additional = 1;
    376   1.1  mrg     }
    377   1.1  mrg   else
    378   1.1  mrg     {
    379   1.1  mrg       /* The low 31 bits of the content field are a self-relative
    380   1.1  mrg 	 offset to an _Unwind_EHT_Entry structure.  */
    381   1.1  mrg       ucbp->pr_cache.ehtp =
    382   1.1  mrg 	(_Unwind_EHT_Header *) selfrel_offset31 (&eitp->content);
    383   1.1  mrg       ucbp->pr_cache.additional = 0;
    384   1.1  mrg     }
    385   1.1  mrg 
    386   1.1  mrg   /* Discover the personality routine address.  */
    387   1.1  mrg   if (*ucbp->pr_cache.ehtp & (1u << 31))
    388   1.1  mrg     {
    389   1.1  mrg       /* One of the predefined standard routines.  */
    390   1.1  mrg       _uw idx = (*(_uw *) ucbp->pr_cache.ehtp >> 24) & 0xf;
    391   1.9  mrg #if __FDPIC__
    392   1.9  mrg       {
    393   1.9  mrg 	struct funcdesc_t *funcdesc
    394   1.9  mrg 	  = (struct funcdesc_t *) __gnu_unwind_get_pr_addr (idx);
    395   1.9  mrg 	if (funcdesc)
    396   1.9  mrg 	  {
    397   1.9  mrg 	    UCB_PR_ADDR (ucbp) = funcdesc->ptr;
    398   1.9  mrg 	    UCB_PR_GOT (ucbp) = funcdesc->got;
    399   1.9  mrg 	  }
    400   1.9  mrg 	else
    401   1.9  mrg 	  UCB_PR_ADDR (ucbp) = 0;
    402   1.9  mrg       }
    403   1.9  mrg #else
    404   1.1  mrg       UCB_PR_ADDR (ucbp) = __gnu_unwind_get_pr_addr (idx);
    405   1.9  mrg #endif
    406   1.1  mrg       if (UCB_PR_ADDR (ucbp) == 0)
    407   1.1  mrg 	{
    408   1.1  mrg 	  /* Failed */
    409   1.1  mrg 	  return _URC_FAILURE;
    410   1.1  mrg 	}
    411   1.1  mrg     }
    412   1.1  mrg   else
    413   1.1  mrg     {
    414   1.1  mrg       /* Execute region offset to PR */
    415   1.1  mrg       UCB_PR_ADDR (ucbp) = selfrel_offset31 (ucbp->pr_cache.ehtp);
    416   1.9  mrg #if __FDPIC__
    417   1.9  mrg       UCB_PR_GOT (ucbp)
    418   1.9  mrg 	= (unsigned int) _Unwind_gnu_Find_got ((_Unwind_Ptr) UCB_PR_ADDR (ucbp));
    419   1.9  mrg #endif
    420   1.1  mrg     }
    421   1.1  mrg   return _URC_OK;
    422   1.1  mrg }
    423   1.1  mrg 
    424   1.1  mrg 
    425   1.1  mrg /* Perform phase2 unwinding.  VRS is the initial virtual register state.  */
    426   1.1  mrg 
    427   1.1  mrg static void __attribute__((noreturn))
    428   1.1  mrg unwind_phase2 (_Unwind_Control_Block * ucbp, phase2_vrs * vrs)
    429   1.1  mrg {
    430   1.1  mrg   _Unwind_Reason_Code pr_result;
    431   1.1  mrg 
    432   1.1  mrg   do
    433   1.1  mrg     {
    434   1.1  mrg       /* Find the entry for this routine.  */
    435   1.1  mrg       if (get_eit_entry (ucbp, VRS_PC(vrs)) != _URC_OK)
    436   1.1  mrg 	abort ();
    437   1.1  mrg 
    438   1.1  mrg       UCB_SAVED_CALLSITE_ADDR (ucbp) = VRS_PC(vrs);
    439   1.1  mrg 
    440   1.1  mrg       /* Call the pr to decide what to do.  */
    441   1.9  mrg #if __FDPIC__
    442   1.9  mrg       {
    443   1.9  mrg 	volatile struct funcdesc_t funcdesc;
    444   1.9  mrg 	funcdesc.ptr = UCB_PR_ADDR (ucbp);
    445   1.9  mrg 	funcdesc.got = UCB_PR_GOT (ucbp);
    446   1.9  mrg 	pr_result = ((personality_routine) &funcdesc)
    447   1.9  mrg 	  (_US_UNWIND_FRAME_STARTING, ucbp, (_Unwind_Context *) vrs);
    448   1.9  mrg       }
    449   1.9  mrg #else
    450   1.1  mrg       pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
    451   1.1  mrg 	(_US_UNWIND_FRAME_STARTING, ucbp, (_Unwind_Context *) vrs);
    452   1.9  mrg #endif
    453   1.1  mrg     }
    454   1.1  mrg   while (pr_result == _URC_CONTINUE_UNWIND);
    455   1.1  mrg 
    456   1.1  mrg   if (pr_result != _URC_INSTALL_CONTEXT)
    457   1.1  mrg     abort();
    458   1.1  mrg 
    459   1.9  mrg #if __FDPIC__
    460   1.9  mrg   /* r9 could have been lost due to PLT jump.  Restore correct value.  */
    461   1.9  mrg   vrs->core.r[FDPIC_REGNUM] = _Unwind_gnu_Find_got (VRS_PC (vrs));
    462   1.9  mrg #endif
    463   1.9  mrg 
    464   1.1  mrg   uw_restore_core_regs (vrs, &vrs->core);
    465   1.1  mrg }
    466   1.1  mrg 
    467   1.1  mrg /* Perform phase2 forced unwinding.  */
    468   1.1  mrg 
    469   1.1  mrg static _Unwind_Reason_Code
    470   1.1  mrg unwind_phase2_forced (_Unwind_Control_Block *ucbp, phase2_vrs *entry_vrs,
    471   1.1  mrg 		      int resuming)
    472   1.1  mrg {
    473   1.1  mrg   _Unwind_Stop_Fn stop_fn = (_Unwind_Stop_Fn) UCB_FORCED_STOP_FN (ucbp);
    474   1.1  mrg   void *stop_arg = (void *)UCB_FORCED_STOP_ARG (ucbp);
    475   1.1  mrg   _Unwind_Reason_Code pr_result = 0;
    476   1.1  mrg   /* We use phase1_vrs here even though we do not demand save, for the
    477   1.1  mrg      prev_sp field.  */
    478   1.1  mrg   phase1_vrs saved_vrs, next_vrs;
    479   1.1  mrg 
    480   1.1  mrg   /* Save the core registers.  */
    481   1.1  mrg   saved_vrs.core = entry_vrs->core;
    482   1.1  mrg   /* We don't need to demand-save the non-core registers, because we
    483   1.1  mrg      unwind in a single pass.  */
    484   1.1  mrg   saved_vrs.demand_save_flags = 0;
    485   1.1  mrg 
    486   1.1  mrg   /* Unwind until we reach a propagation barrier.  */
    487   1.1  mrg   do
    488   1.1  mrg     {
    489   1.1  mrg       _Unwind_State action;
    490   1.1  mrg       _Unwind_Reason_Code entry_code;
    491   1.1  mrg       _Unwind_Reason_Code stop_code;
    492   1.1  mrg 
    493   1.1  mrg       /* Find the entry for this routine.  */
    494   1.1  mrg       entry_code = get_eit_entry (ucbp, VRS_PC (&saved_vrs));
    495   1.1  mrg 
    496   1.1  mrg       if (resuming)
    497   1.1  mrg 	{
    498   1.1  mrg 	  action = _US_UNWIND_FRAME_RESUME | _US_FORCE_UNWIND;
    499   1.1  mrg 	  resuming = 0;
    500   1.1  mrg 	}
    501   1.1  mrg       else
    502   1.1  mrg 	action = _US_UNWIND_FRAME_STARTING | _US_FORCE_UNWIND;
    503   1.1  mrg 
    504   1.1  mrg       if (entry_code == _URC_OK)
    505   1.1  mrg 	{
    506   1.1  mrg 	  UCB_SAVED_CALLSITE_ADDR (ucbp) = VRS_PC (&saved_vrs);
    507   1.1  mrg 
    508   1.1  mrg 	  next_vrs = saved_vrs;
    509   1.1  mrg 
    510   1.1  mrg 	  /* Call the pr to decide what to do.  */
    511   1.9  mrg #if __FDPIC__
    512   1.9  mrg 	  {
    513   1.9  mrg 	    volatile struct funcdesc_t funcdesc;
    514   1.9  mrg 	    funcdesc.ptr = UCB_PR_ADDR (ucbp);
    515   1.9  mrg 	    funcdesc.got = UCB_PR_GOT (ucbp);
    516   1.9  mrg 	    pr_result = ((personality_routine) &funcdesc)
    517   1.9  mrg 	      (action, ucbp, (void *) &next_vrs);
    518   1.9  mrg 	  }
    519   1.9  mrg #else
    520   1.1  mrg 	  pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
    521   1.1  mrg 	    (action, ucbp, (void *) &next_vrs);
    522   1.9  mrg #endif
    523   1.1  mrg 
    524   1.1  mrg 	  saved_vrs.prev_sp = VRS_SP (&next_vrs);
    525   1.1  mrg 	}
    526   1.1  mrg       else
    527   1.1  mrg 	{
    528   1.1  mrg 	  /* Treat any failure as the end of unwinding, to cope more
    529   1.1  mrg 	     gracefully with missing EH information.  Mixed EH and
    530   1.1  mrg 	     non-EH within one object will usually result in failure,
    531   1.1  mrg 	     because the .ARM.exidx tables do not indicate the end
    532   1.1  mrg 	     of the code to which they apply; but mixed EH and non-EH
    533   1.1  mrg 	     shared objects should return an unwind failure at the
    534   1.1  mrg 	     entry of a non-EH shared object.  */
    535   1.1  mrg 	  action |= _US_END_OF_STACK;
    536   1.1  mrg 
    537   1.1  mrg 	  saved_vrs.prev_sp = VRS_SP (&saved_vrs);
    538   1.1  mrg 	}
    539   1.1  mrg 
    540   1.1  mrg       stop_code = stop_fn (1, action, ucbp->exception_class, ucbp,
    541   1.1  mrg 			   (void *)&saved_vrs, stop_arg);
    542   1.1  mrg       if (stop_code != _URC_NO_REASON)
    543   1.1  mrg 	return _URC_FAILURE;
    544   1.1  mrg 
    545   1.1  mrg       if (entry_code != _URC_OK)
    546   1.1  mrg 	return entry_code;
    547   1.1  mrg 
    548   1.1  mrg       saved_vrs = next_vrs;
    549   1.1  mrg     }
    550   1.1  mrg   while (pr_result == _URC_CONTINUE_UNWIND);
    551   1.1  mrg 
    552   1.1  mrg   if (pr_result != _URC_INSTALL_CONTEXT)
    553   1.1  mrg     {
    554   1.1  mrg       /* Some sort of failure has occurred in the pr and probably the
    555   1.1  mrg 	 pr returned _URC_FAILURE.  */
    556   1.1  mrg       return _URC_FAILURE;
    557   1.1  mrg     }
    558   1.1  mrg 
    559   1.9  mrg #if __FDPIC__
    560   1.9  mrg   /* r9 could have been lost due to PLT jump.  Restore correct value.  */
    561   1.9  mrg   saved_vrs.core.r[FDPIC_REGNUM] = _Unwind_gnu_Find_got (VRS_PC (&saved_vrs));
    562   1.9  mrg #endif
    563   1.9  mrg 
    564   1.1  mrg   uw_restore_core_regs (&saved_vrs, &saved_vrs.core);
    565   1.1  mrg }
    566   1.1  mrg 
    567   1.1  mrg /* This is a very limited implementation of _Unwind_GetCFA.  It returns
    568   1.1  mrg    the stack pointer as it is about to be unwound, and is only valid
    569   1.1  mrg    while calling the stop function during forced unwinding.  If the
    570   1.1  mrg    current personality routine result is going to run a cleanup, this
    571   1.1  mrg    will not be the CFA; but when the frame is really unwound, it will
    572   1.1  mrg    be.  */
    573   1.1  mrg 
    574   1.1  mrg _Unwind_Word
    575   1.1  mrg _Unwind_GetCFA (_Unwind_Context *context)
    576   1.1  mrg {
    577   1.1  mrg   return ((phase1_vrs *) context)->prev_sp;
    578   1.1  mrg }
    579   1.1  mrg 
    580   1.1  mrg /* Perform phase1 unwinding.  UCBP is the exception being thrown, and
    581   1.1  mrg    entry_VRS is the register state on entry to _Unwind_RaiseException.  */
    582   1.1  mrg 
    583   1.1  mrg _Unwind_Reason_Code
    584   1.1  mrg __gnu_Unwind_RaiseException (_Unwind_Control_Block *, phase2_vrs *);
    585   1.1  mrg 
    586   1.1  mrg _Unwind_Reason_Code
    587   1.1  mrg __gnu_Unwind_RaiseException (_Unwind_Control_Block * ucbp,
    588   1.1  mrg 			     phase2_vrs * entry_vrs)
    589   1.1  mrg {
    590   1.1  mrg   phase1_vrs saved_vrs;
    591   1.1  mrg   _Unwind_Reason_Code pr_result;
    592   1.1  mrg 
    593   1.1  mrg   /* Set the pc to the call site.  */
    594   1.1  mrg   VRS_PC (entry_vrs) = VRS_RETURN(entry_vrs);
    595   1.1  mrg 
    596   1.1  mrg   /* Save the core registers.  */
    597   1.1  mrg   saved_vrs.core = entry_vrs->core;
    598   1.1  mrg   /* Set demand-save flags.  */
    599   1.1  mrg   saved_vrs.demand_save_flags = ~(_uw) 0;
    600   1.1  mrg 
    601   1.1  mrg   /* Unwind until we reach a propagation barrier.  */
    602   1.1  mrg   do
    603   1.1  mrg     {
    604   1.1  mrg       /* Find the entry for this routine.  */
    605   1.1  mrg       if (get_eit_entry (ucbp, VRS_PC (&saved_vrs)) != _URC_OK)
    606   1.1  mrg 	return _URC_FAILURE;
    607   1.1  mrg 
    608   1.1  mrg       /* Call the pr to decide what to do.  */
    609   1.9  mrg #if __FDPIC__
    610   1.9  mrg       {
    611   1.9  mrg 	volatile struct funcdesc_t funcdesc;
    612   1.9  mrg 	funcdesc.ptr = UCB_PR_ADDR (ucbp);
    613   1.9  mrg 	funcdesc.got = UCB_PR_GOT (ucbp);
    614   1.9  mrg 	pr_result = ((personality_routine) &funcdesc)
    615   1.9  mrg 	  (_US_VIRTUAL_UNWIND_FRAME, ucbp, (void *) &saved_vrs);
    616   1.9  mrg       }
    617   1.9  mrg #else
    618   1.1  mrg       pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
    619   1.1  mrg 	(_US_VIRTUAL_UNWIND_FRAME, ucbp, (void *) &saved_vrs);
    620   1.9  mrg #endif
    621   1.1  mrg     }
    622   1.1  mrg   while (pr_result == _URC_CONTINUE_UNWIND);
    623   1.1  mrg 
    624   1.1  mrg   /* We've unwound as far as we want to go, so restore the original
    625   1.1  mrg      register state.  */
    626   1.1  mrg   restore_non_core_regs (&saved_vrs);
    627   1.1  mrg   if (pr_result != _URC_HANDLER_FOUND)
    628   1.1  mrg     {
    629   1.1  mrg       /* Some sort of failure has occurred in the pr and probably the
    630   1.1  mrg 	 pr returned _URC_FAILURE.  */
    631   1.1  mrg       return _URC_FAILURE;
    632   1.1  mrg     }
    633   1.1  mrg 
    634   1.1  mrg   unwind_phase2 (ucbp, entry_vrs);
    635   1.1  mrg }
    636   1.1  mrg 
    637   1.1  mrg /* Resume unwinding after a cleanup has been run.  UCBP is the exception
    638   1.1  mrg    being thrown and ENTRY_VRS is the register state on entry to
    639   1.1  mrg    _Unwind_Resume.  */
    640   1.1  mrg _Unwind_Reason_Code
    641   1.1  mrg __gnu_Unwind_ForcedUnwind (_Unwind_Control_Block *,
    642   1.1  mrg 			   _Unwind_Stop_Fn, void *, phase2_vrs *);
    643   1.1  mrg 
    644   1.1  mrg _Unwind_Reason_Code
    645   1.1  mrg __gnu_Unwind_ForcedUnwind (_Unwind_Control_Block *ucbp,
    646   1.1  mrg 			   _Unwind_Stop_Fn stop_fn, void *stop_arg,
    647   1.1  mrg 			   phase2_vrs *entry_vrs)
    648   1.1  mrg {
    649   1.1  mrg   UCB_FORCED_STOP_FN (ucbp) = (_uw) stop_fn;
    650   1.1  mrg   UCB_FORCED_STOP_ARG (ucbp) = (_uw) stop_arg;
    651   1.1  mrg 
    652   1.1  mrg   /* Set the pc to the call site.  */
    653   1.1  mrg   VRS_PC (entry_vrs) = VRS_RETURN(entry_vrs);
    654   1.1  mrg 
    655   1.1  mrg   return unwind_phase2_forced (ucbp, entry_vrs, 0);
    656   1.1  mrg }
    657   1.1  mrg 
    658   1.1  mrg _Unwind_Reason_Code
    659   1.1  mrg __gnu_Unwind_Resume (_Unwind_Control_Block *, phase2_vrs *);
    660   1.1  mrg 
    661   1.1  mrg _Unwind_Reason_Code
    662   1.1  mrg __gnu_Unwind_Resume (_Unwind_Control_Block * ucbp, phase2_vrs * entry_vrs)
    663   1.1  mrg {
    664   1.1  mrg   _Unwind_Reason_Code pr_result;
    665   1.1  mrg 
    666   1.1  mrg   /* Recover the saved address.  */
    667   1.1  mrg   VRS_PC (entry_vrs) = UCB_SAVED_CALLSITE_ADDR (ucbp);
    668   1.1  mrg 
    669   1.1  mrg   if (UCB_FORCED_STOP_FN (ucbp))
    670   1.1  mrg     {
    671   1.1  mrg       unwind_phase2_forced (ucbp, entry_vrs, 1);
    672   1.1  mrg 
    673   1.1  mrg       /* We can't return failure at this point.  */
    674   1.1  mrg       abort ();
    675   1.1  mrg     }
    676   1.1  mrg 
    677   1.1  mrg   /* Call the cached PR.  */
    678   1.9  mrg #if __FDPIC__
    679   1.9  mrg   {
    680   1.9  mrg     volatile struct funcdesc_t funcdesc;
    681   1.9  mrg     funcdesc.ptr = UCB_PR_ADDR (ucbp);
    682   1.9  mrg     funcdesc.got = UCB_PR_GOT (ucbp);
    683   1.9  mrg     pr_result = ((personality_routine) &funcdesc)
    684   1.9  mrg       (_US_UNWIND_FRAME_RESUME, ucbp, (_Unwind_Context *) entry_vrs);
    685   1.9  mrg   }
    686   1.9  mrg #else
    687   1.1  mrg   pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
    688   1.1  mrg 	(_US_UNWIND_FRAME_RESUME, ucbp, (_Unwind_Context *) entry_vrs);
    689   1.9  mrg #endif
    690   1.1  mrg 
    691   1.1  mrg   switch (pr_result)
    692   1.1  mrg     {
    693   1.1  mrg     case _URC_INSTALL_CONTEXT:
    694   1.1  mrg       /* Upload the registers to enter the landing pad.  */
    695   1.9  mrg #if __FDPIC__
    696   1.9  mrg       /* r9 could have been lost due to PLT jump.  Restore correct value.  */
    697   1.9  mrg       entry_vrs->core.r[FDPIC_REGNUM] = _Unwind_gnu_Find_got (VRS_PC (entry_vrs));
    698   1.9  mrg #endif
    699   1.1  mrg       uw_restore_core_regs (entry_vrs, &entry_vrs->core);
    700   1.1  mrg 
    701   1.1  mrg     case _URC_CONTINUE_UNWIND:
    702   1.1  mrg       /* Continue unwinding the next frame.  */
    703   1.1  mrg       unwind_phase2 (ucbp, entry_vrs);
    704   1.1  mrg 
    705   1.1  mrg     default:
    706   1.1  mrg       abort ();
    707   1.1  mrg     }
    708   1.1  mrg }
    709   1.1  mrg 
    710   1.1  mrg _Unwind_Reason_Code
    711   1.1  mrg __gnu_Unwind_Resume_or_Rethrow (_Unwind_Control_Block *, phase2_vrs *);
    712   1.1  mrg 
    713   1.1  mrg _Unwind_Reason_Code
    714   1.1  mrg __gnu_Unwind_Resume_or_Rethrow (_Unwind_Control_Block * ucbp,
    715   1.1  mrg 				phase2_vrs * entry_vrs)
    716   1.1  mrg {
    717   1.1  mrg   if (!UCB_FORCED_STOP_FN (ucbp))
    718   1.1  mrg     return __gnu_Unwind_RaiseException (ucbp, entry_vrs);
    719   1.1  mrg 
    720   1.1  mrg   /* Set the pc to the call site.  */
    721   1.1  mrg   VRS_PC (entry_vrs) = VRS_RETURN (entry_vrs);
    722   1.1  mrg   /* Continue unwinding the next frame.  */
    723   1.1  mrg   return unwind_phase2_forced (ucbp, entry_vrs, 0);
    724   1.1  mrg }
    725   1.1  mrg 
    726   1.1  mrg /* Clean up an exception object when unwinding is complete.  */
    727   1.1  mrg void
    728   1.1  mrg _Unwind_Complete (_Unwind_Control_Block * ucbp __attribute__((unused)))
    729   1.1  mrg {
    730   1.1  mrg }
    731   1.1  mrg 
    732   1.1  mrg 
    733   1.1  mrg /* Free an exception.  */
    734   1.1  mrg 
    735   1.1  mrg void
    736   1.1  mrg _Unwind_DeleteException (_Unwind_Exception * exc)
    737   1.1  mrg {
    738   1.1  mrg   if (exc->exception_cleanup)
    739   1.1  mrg     (*exc->exception_cleanup) (_URC_FOREIGN_EXCEPTION_CAUGHT, exc);
    740   1.1  mrg }
    741   1.1  mrg 
    742   1.1  mrg 
    743   1.1  mrg /* Perform stack backtrace through unwind data.  */
    744   1.1  mrg _Unwind_Reason_Code
    745   1.1  mrg __gnu_Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument,
    746   1.1  mrg 		       phase2_vrs * entry_vrs);
    747   1.1  mrg _Unwind_Reason_Code
    748   1.1  mrg __gnu_Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument,
    749   1.1  mrg 		       phase2_vrs * entry_vrs)
    750   1.1  mrg {
    751   1.1  mrg   phase1_vrs saved_vrs;
    752   1.1  mrg   _Unwind_Reason_Code code;
    753   1.1  mrg 
    754   1.1  mrg   _Unwind_Control_Block ucb;
    755   1.1  mrg   _Unwind_Control_Block *ucbp = &ucb;
    756   1.1  mrg 
    757   1.1  mrg   /* Set the pc to the call site.  */
    758   1.1  mrg   VRS_PC (entry_vrs) = VRS_RETURN (entry_vrs);
    759   1.1  mrg 
    760   1.1  mrg   /* Save the core registers.  */
    761   1.1  mrg   saved_vrs.core = entry_vrs->core;
    762   1.1  mrg   /* Set demand-save flags.  */
    763   1.1  mrg   saved_vrs.demand_save_flags = ~(_uw) 0;
    764   1.1  mrg 
    765   1.1  mrg   do
    766   1.1  mrg     {
    767   1.1  mrg       /* Find the entry for this routine.  */
    768   1.1  mrg       if (get_eit_entry (ucbp, VRS_PC (&saved_vrs)) != _URC_OK)
    769   1.1  mrg 	{
    770   1.1  mrg 	  code = _URC_FAILURE;
    771   1.1  mrg 	  break;
    772   1.1  mrg 	}
    773   1.1  mrg 
    774   1.1  mrg       /* The dwarf unwinder assumes the context structure holds things
    775   1.1  mrg 	 like the function and LSDA pointers.  The ARM implementation
    776   1.1  mrg 	 caches these in the exception header (UCB).  To avoid
    777   1.1  mrg 	 rewriting everything we make the virtual IP register point at
    778   1.1  mrg 	 the UCB.  */
    779   1.1  mrg       _Unwind_SetGR((_Unwind_Context *)&saved_vrs, UNWIND_POINTER_REG, (_Unwind_Ptr) ucbp);
    780   1.1  mrg 
    781   1.1  mrg       /* Call trace function.  */
    782   1.1  mrg       if ((*trace) ((_Unwind_Context *) &saved_vrs, trace_argument)
    783   1.1  mrg 	  != _URC_NO_REASON)
    784   1.1  mrg 	{
    785   1.1  mrg 	  code = _URC_FAILURE;
    786   1.1  mrg 	  break;
    787   1.1  mrg 	}
    788   1.1  mrg 
    789   1.1  mrg       /* Call the pr to decide what to do.  */
    790   1.9  mrg #if __FDPIC__
    791   1.9  mrg       {
    792   1.9  mrg 	volatile struct funcdesc_t funcdesc;
    793   1.9  mrg 	funcdesc.ptr = UCB_PR_ADDR (ucbp);
    794   1.9  mrg 	funcdesc.got = UCB_PR_GOT (ucbp);
    795   1.9  mrg 	code = ((personality_routine) &funcdesc)
    796   1.9  mrg 	  (_US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND,
    797   1.9  mrg 	   ucbp, (void *) &saved_vrs);
    798   1.9  mrg       }
    799   1.9  mrg #else
    800   1.1  mrg       code = ((personality_routine) UCB_PR_ADDR (ucbp))
    801   1.1  mrg 	(_US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND,
    802   1.1  mrg 	 ucbp, (void *) &saved_vrs);
    803   1.9  mrg #endif
    804   1.1  mrg     }
    805   1.1  mrg   while (code != _URC_END_OF_STACK
    806   1.1  mrg 	 && code != _URC_FAILURE);
    807   1.1  mrg 
    808   1.1  mrg   restore_non_core_regs (&saved_vrs);
    809   1.1  mrg   return code;
    810   1.1  mrg }
    811   1.1  mrg 
    812   1.1  mrg 
    813   1.1  mrg /* Common implementation for ARM ABI defined personality routines.
    814   1.1  mrg    ID is the index of the personality routine, other arguments are as defined
    815   1.1  mrg    by __aeabi_unwind_cpp_pr{0,1,2}.  */
    816   1.1  mrg 
    817   1.1  mrg static _Unwind_Reason_Code
    818   1.1  mrg __gnu_unwind_pr_common (_Unwind_State state,
    819   1.1  mrg 			_Unwind_Control_Block *ucbp,
    820   1.1  mrg 			_Unwind_Context *context,
    821   1.1  mrg 			int id)
    822   1.1  mrg {
    823   1.1  mrg   __gnu_unwind_state uws;
    824   1.1  mrg   _uw *data;
    825   1.1  mrg   _uw offset;
    826   1.1  mrg   _uw len;
    827   1.1  mrg   _uw rtti_count;
    828   1.1  mrg   int phase2_call_unexpected_after_unwind = 0;
    829   1.1  mrg   int in_range = 0;
    830   1.1  mrg   int forced_unwind = state & _US_FORCE_UNWIND;
    831   1.1  mrg 
    832   1.1  mrg   state &= _US_ACTION_MASK;
    833   1.1  mrg 
    834   1.1  mrg   data = (_uw *) ucbp->pr_cache.ehtp;
    835   1.1  mrg   uws.data = *(data++);
    836   1.1  mrg   uws.next = data;
    837   1.1  mrg   if (id == 0)
    838   1.1  mrg     {
    839   1.1  mrg       uws.data <<= 8;
    840   1.1  mrg       uws.words_left = 0;
    841   1.1  mrg       uws.bytes_left = 3;
    842   1.1  mrg     }
    843   1.1  mrg   else if (id < 3)
    844   1.1  mrg     {
    845   1.1  mrg       uws.words_left = (uws.data >> 16) & 0xff;
    846   1.1  mrg       uws.data <<= 16;
    847   1.1  mrg       uws.bytes_left = 2;
    848   1.1  mrg       data += uws.words_left;
    849   1.1  mrg     }
    850   1.1  mrg 
    851   1.1  mrg   /* Restore the saved pointer.  */
    852   1.1  mrg   if (state == _US_UNWIND_FRAME_RESUME)
    853   1.1  mrg     data = (_uw *) ucbp->cleanup_cache.bitpattern[0];
    854   1.1  mrg 
    855   1.1  mrg   if ((ucbp->pr_cache.additional & 1) == 0)
    856   1.1  mrg     {
    857   1.1  mrg       /* Process descriptors.  */
    858   1.1  mrg       while (*data)
    859   1.1  mrg 	{
    860   1.1  mrg 	  _uw addr;
    861   1.1  mrg 	  _uw fnstart;
    862   1.1  mrg 
    863   1.1  mrg 	  if (id == 2)
    864   1.1  mrg 	    {
    865   1.1  mrg 	      len = ((EHT32 *) data)->length;
    866   1.1  mrg 	      offset = ((EHT32 *) data)->offset;
    867   1.1  mrg 	      data += 2;
    868   1.1  mrg 	    }
    869   1.1  mrg 	  else
    870   1.1  mrg 	    {
    871   1.1  mrg 	      len = ((EHT16 *) data)->length;
    872   1.1  mrg 	      offset = ((EHT16 *) data)->offset;
    873   1.1  mrg 	      data++;
    874   1.1  mrg 	    }
    875   1.1  mrg 
    876   1.1  mrg 	  fnstart = ucbp->pr_cache.fnstart + (offset & ~1);
    877   1.1  mrg 	  addr = _Unwind_GetGR (context, R_PC);
    878   1.1  mrg 	  in_range = (fnstart <= addr && addr < fnstart + (len & ~1));
    879   1.1  mrg 
    880   1.1  mrg 	  switch (((offset & 1) << 1) | (len & 1))
    881   1.1  mrg 	    {
    882   1.1  mrg 	    case 0:
    883   1.1  mrg 	      /* Cleanup.  */
    884   1.1  mrg 	      if (state != _US_VIRTUAL_UNWIND_FRAME
    885   1.1  mrg 		  && in_range)
    886   1.1  mrg 		{
    887   1.1  mrg 		  /* Cleanup in range, and we are running cleanups.  */
    888   1.1  mrg 		  _uw lp;
    889   1.1  mrg 
    890   1.1  mrg 		  /* Landing pad address is 31-bit pc-relative offset.  */
    891   1.1  mrg 		  lp = selfrel_offset31 (data);
    892   1.1  mrg 		  data++;
    893   1.1  mrg 		  /* Save the exception data pointer.  */
    894   1.1  mrg 		  ucbp->cleanup_cache.bitpattern[0] = (_uw) data;
    895   1.1  mrg 		  if (!__cxa_begin_cleanup (ucbp))
    896   1.1  mrg 		    return _URC_FAILURE;
    897   1.1  mrg 		  /* Setup the VRS to enter the landing pad.  */
    898   1.1  mrg 		  _Unwind_SetGR (context, R_PC, lp);
    899   1.1  mrg 		  return _URC_INSTALL_CONTEXT;
    900   1.1  mrg 		}
    901   1.1  mrg 	      /* Cleanup not in range, or we are in stage 1.  */
    902   1.1  mrg 	      data++;
    903   1.1  mrg 	      break;
    904   1.1  mrg 
    905   1.1  mrg 	    case 1:
    906   1.1  mrg 	      /* Catch handler.  */
    907   1.1  mrg 	      if (state == _US_VIRTUAL_UNWIND_FRAME)
    908   1.1  mrg 		{
    909   1.1  mrg 		  if (in_range)
    910   1.1  mrg 		    {
    911   1.1  mrg 		      /* Check for a barrier.  */
    912   1.1  mrg 		      _uw rtti;
    913   1.1  mrg 		      bool is_reference = (data[0] & uint32_highbit) != 0;
    914   1.1  mrg 		      void *matched;
    915   1.1  mrg 		      enum __cxa_type_match_result match_type;
    916   1.1  mrg 
    917   1.1  mrg 		      /* Check for no-throw areas.  */
    918   1.1  mrg 		      if (data[1] == (_uw) -2)
    919   1.1  mrg 			return _URC_FAILURE;
    920   1.1  mrg 
    921   1.1  mrg 		      /* The thrown object immediately follows the ECB.  */
    922   1.1  mrg 		      matched = (void *)(ucbp + 1);
    923   1.1  mrg 		      if (data[1] != (_uw) -1)
    924   1.1  mrg 			{
    925   1.1  mrg 			  /* Match a catch specification.  */
    926   1.1  mrg 			  rtti = _Unwind_decode_typeinfo_ptr (0,
    927   1.1  mrg 							      (_uw) &data[1]);
    928   1.1  mrg 			  match_type = __cxa_type_match (ucbp,
    929   1.1  mrg 							 (type_info *) rtti,
    930   1.1  mrg 							 is_reference,
    931   1.1  mrg 							 &matched);
    932   1.1  mrg 			}
    933   1.1  mrg 		      else
    934   1.1  mrg 			match_type = ctm_succeeded;
    935   1.1  mrg 
    936   1.1  mrg 		      if (match_type)
    937   1.1  mrg 			{
    938   1.1  mrg 			  ucbp->barrier_cache.sp =
    939   1.1  mrg 			    _Unwind_GetGR (context, R_SP);
    940   1.1  mrg 			  // ctm_succeeded_with_ptr_to_base really
    941   1.1  mrg 			  // means _c_t_m indirected the pointer
    942   1.1  mrg 			  // object.  We have to reconstruct the
    943   1.1  mrg 			  // additional pointer layer by using a temporary.
    944   1.1  mrg 			  if (match_type == ctm_succeeded_with_ptr_to_base)
    945   1.1  mrg 			    {
    946   1.1  mrg 			      ucbp->barrier_cache.bitpattern[2]
    947   1.1  mrg 				= (_uw) matched;
    948   1.1  mrg 			      ucbp->barrier_cache.bitpattern[0]
    949   1.1  mrg 				= (_uw) &ucbp->barrier_cache.bitpattern[2];
    950   1.1  mrg 			    }
    951   1.1  mrg 			  else
    952   1.1  mrg 			    ucbp->barrier_cache.bitpattern[0] = (_uw) matched;
    953   1.1  mrg 			  ucbp->barrier_cache.bitpattern[1] = (_uw) data;
    954   1.1  mrg 			  return _URC_HANDLER_FOUND;
    955   1.1  mrg 			}
    956   1.1  mrg 		    }
    957   1.1  mrg 		  /* Handler out of range, or not matched.  */
    958   1.1  mrg 		}
    959   1.1  mrg 	      else if (ucbp->barrier_cache.sp == _Unwind_GetGR (context, R_SP)
    960   1.1  mrg 		       && ucbp->barrier_cache.bitpattern[1] == (_uw) data)
    961   1.1  mrg 		{
    962   1.1  mrg 		  /* Matched a previous propagation barrier.  */
    963   1.1  mrg 		  _uw lp;
    964   1.1  mrg 
    965   1.1  mrg 		  /* Setup for entry to the handler.  */
    966   1.1  mrg 		  lp = selfrel_offset31 (data);
    967   1.1  mrg 		  _Unwind_SetGR (context, R_PC, lp);
    968   1.1  mrg 		  _Unwind_SetGR (context, 0, (_uw) ucbp);
    969   1.1  mrg 		  return _URC_INSTALL_CONTEXT;
    970   1.1  mrg 		}
    971   1.1  mrg 	      /* Catch handler not matched.  Advance to the next descriptor.  */
    972   1.1  mrg 	      data += 2;
    973   1.1  mrg 	      break;
    974   1.1  mrg 
    975   1.1  mrg 	    case 2:
    976   1.1  mrg 	      rtti_count = data[0] & 0x7fffffff;
    977   1.1  mrg 	      /* Exception specification.  */
    978   1.1  mrg 	      if (state == _US_VIRTUAL_UNWIND_FRAME)
    979   1.1  mrg 		{
    980   1.1  mrg 		  if (in_range && (!forced_unwind || !rtti_count))
    981   1.1  mrg 		    {
    982   1.1  mrg 		      /* Match against the exception specification.  */
    983   1.1  mrg 		      _uw i;
    984   1.1  mrg 		      _uw rtti;
    985   1.1  mrg 		      void *matched;
    986   1.1  mrg 
    987   1.1  mrg 		      for (i = 0; i < rtti_count; i++)
    988   1.1  mrg 			{
    989   1.1  mrg 			  matched = (void *)(ucbp + 1);
    990   1.1  mrg 			  rtti = _Unwind_decode_typeinfo_ptr (0,
    991   1.1  mrg 			      (_uw) &data[i + 1]);
    992   1.1  mrg 			  if (__cxa_type_match (ucbp, (type_info *) rtti, 0,
    993   1.1  mrg 						&matched))
    994   1.1  mrg 			    break;
    995   1.1  mrg 			}
    996   1.1  mrg 
    997   1.1  mrg 		      if (i == rtti_count)
    998   1.1  mrg 			{
    999   1.1  mrg 			  /* Exception does not match the spec.  */
   1000   1.1  mrg 			  ucbp->barrier_cache.sp =
   1001   1.1  mrg 			    _Unwind_GetGR (context, R_SP);
   1002   1.1  mrg 			  ucbp->barrier_cache.bitpattern[0] = (_uw) matched;
   1003   1.1  mrg 			  ucbp->barrier_cache.bitpattern[1] = (_uw) data;
   1004   1.1  mrg 			  return _URC_HANDLER_FOUND;
   1005   1.1  mrg 			}
   1006   1.1  mrg 		    }
   1007   1.1  mrg 		  /* Handler out of range, or exception is permitted.  */
   1008   1.1  mrg 		}
   1009   1.1  mrg 	      else if (ucbp->barrier_cache.sp == _Unwind_GetGR (context, R_SP)
   1010   1.1  mrg 		       && ucbp->barrier_cache.bitpattern[1] == (_uw) data)
   1011   1.1  mrg 		{
   1012   1.1  mrg 		  /* Matched a previous propagation barrier.  */
   1013   1.1  mrg 		  _uw lp;
   1014   1.1  mrg 		  /* Record the RTTI list for __cxa_call_unexpected.  */
   1015   1.1  mrg 		  ucbp->barrier_cache.bitpattern[1] = rtti_count;
   1016   1.1  mrg 		  ucbp->barrier_cache.bitpattern[2] = 0;
   1017   1.1  mrg 		  ucbp->barrier_cache.bitpattern[3] = 4;
   1018   1.1  mrg 		  ucbp->barrier_cache.bitpattern[4] = (_uw) &data[1];
   1019   1.1  mrg 
   1020   1.1  mrg 		  if (data[0] & uint32_highbit)
   1021   1.1  mrg 		    {
   1022   1.1  mrg 		      data += rtti_count + 1;
   1023   1.1  mrg 		      /* Setup for entry to the handler.  */
   1024   1.1  mrg 		      lp = selfrel_offset31 (data);
   1025   1.1  mrg 		      data++;
   1026   1.1  mrg 		      _Unwind_SetGR (context, R_PC, lp);
   1027   1.1  mrg 		      _Unwind_SetGR (context, 0, (_uw) ucbp);
   1028   1.1  mrg 		      return _URC_INSTALL_CONTEXT;
   1029   1.1  mrg 		    }
   1030   1.1  mrg 		  else
   1031   1.1  mrg 		    phase2_call_unexpected_after_unwind = 1;
   1032   1.1  mrg 		}
   1033   1.1  mrg 	      if (data[0] & uint32_highbit)
   1034   1.1  mrg 		data++;
   1035   1.1  mrg 	      data += rtti_count + 1;
   1036   1.1  mrg 	      break;
   1037   1.1  mrg 
   1038   1.1  mrg 	    default:
   1039   1.1  mrg 	      /* Should never happen.  */
   1040   1.1  mrg 	      return _URC_FAILURE;
   1041   1.1  mrg 	    }
   1042   1.1  mrg 	  /* Finished processing this descriptor.  */
   1043   1.1  mrg 	}
   1044   1.1  mrg     }
   1045   1.1  mrg 
   1046   1.1  mrg   if (id >= 3)
   1047   1.1  mrg     {
   1048   1.1  mrg       /* 24-bit ecoding */
   1049   1.1  mrg       if (__gnu_unwind_24bit (context, uws.data, id == 4) != _URC_OK)
   1050   1.1  mrg 	return _URC_FAILURE;
   1051   1.1  mrg     }
   1052   1.1  mrg   else
   1053   1.1  mrg     {
   1054   1.1  mrg       if (__gnu_unwind_execute (context, &uws) != _URC_OK)
   1055   1.1  mrg 	return _URC_FAILURE;
   1056   1.1  mrg     }
   1057   1.1  mrg 
   1058   1.1  mrg   if (phase2_call_unexpected_after_unwind)
   1059   1.1  mrg     {
   1060   1.1  mrg       /* Enter __cxa_unexpected as if called from the call site.  */
   1061   1.1  mrg       _Unwind_SetGR (context, R_LR, _Unwind_GetGR (context, R_PC));
   1062   1.1  mrg       _Unwind_SetGR (context, R_PC, (_uw) &__cxa_call_unexpected);
   1063   1.1  mrg       return _URC_INSTALL_CONTEXT;
   1064   1.1  mrg     }
   1065   1.1  mrg 
   1066   1.1  mrg   return _URC_CONTINUE_UNWIND;
   1067   1.1  mrg }
   1068