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