Implement protection of global variables
[official-gcc.git] / libgcc / unwind-arm-common.inc
blobbf1690200b8d26d42bd364b5a9c36ad4ea80b374
1 /* Common unwinding code for ARM EABI and C6X.
2    Copyright (C) 2004, 2005, 2009, 2011 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 /* We add a prototype for abort here to avoid creating a dependency on
34    target headers.  */
35 extern void abort (void);
37 /* Definitions for C++ runtime support routines.  We make these weak
38    declarations to avoid pulling in libsupc++ unnecessarily.  */
39 typedef unsigned char bool;
41 typedef struct _ZSt9type_info type_info; /* This names C++ type_info type */
42 enum __cxa_type_match_result
43   {
44     ctm_failed = 0,
45     ctm_succeeded = 1,
46     ctm_succeeded_with_ptr_to_base = 2
47   };
49 void __attribute__((weak)) __cxa_call_unexpected(_Unwind_Control_Block *ucbp);
50 bool __attribute__((weak)) __cxa_begin_cleanup(_Unwind_Control_Block *ucbp);
51 enum __cxa_type_match_result __attribute__((weak)) __cxa_type_match
52   (_Unwind_Control_Block *ucbp, const type_info *rttip,
53    bool is_reference, void **matched_object);
55 _Unwind_Ptr __attribute__((weak))
56 __gnu_Unwind_Find_exidx (_Unwind_Ptr, int *);
58 #define EXIDX_CANTUNWIND 1
59 #define uint32_highbit (((_uw) 1) << 31)
61 #define UCB_FORCED_STOP_FN(ucbp) ((ucbp)->unwinder_cache.reserved1)
62 #define UCB_PR_ADDR(ucbp) ((ucbp)->unwinder_cache.reserved2)
63 #define UCB_SAVED_CALLSITE_ADDR(ucbp) ((ucbp)->unwinder_cache.reserved3)
64 #define UCB_FORCED_STOP_ARG(ucbp) ((ucbp)->unwinder_cache.reserved4)
66 /* Unwind descriptors.  */
68 typedef struct
70   _uw16 length;
71   _uw16 offset;
72 } EHT16;
74 typedef struct
76   _uw length;
77   _uw offset;
78 } EHT32;
80 /* An exception index table entry.  */
82 typedef struct __EIT_entry
84   _uw fnoffset;
85   _uw content;
86 } __EIT_entry;
88 /* Assembly helper functions.  */
90 /* Restore core register state.  Never returns.  */
91 void __attribute__((noreturn)) restore_core_regs (struct core_regs *);
94 /* Restore coprocessor state after phase1 unwinding.  */
95 static void restore_non_core_regs (phase1_vrs * vrs);
97 /* A better way to do this would probably be to compare the absolute address
98    with a segment relative relocation of the same symbol.  */
100 extern int __text_start;
101 extern int __data_start;
103 /* The exception index table location.  */
104 extern __EIT_entry __exidx_start;
105 extern __EIT_entry __exidx_end;
107 /* Core unwinding functions.  */
109 /* Calculate the address encoded by a 31-bit self-relative offset at address
110    P.  */
111 static inline _uw selfrel_offset31 (const _uw *p);
113 static _uw __gnu_unwind_get_pr_addr (int idx);
115 static void _Unwind_DebugHook (void *, void *)
116   __attribute__ ((__noinline__, __used__, __noclone__));
118 /* This function is called during unwinding.  It is intended as a hook
119    for a debugger to intercept exceptions.  CFA is the CFA of the
120    target frame.  HANDLER is the PC to which control will be
121    transferred.  */
123 static void
124 _Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
125                    void *handler __attribute__ ((__unused__)))
127   /* We only want to use stap probes starting with v3.  Earlier
128      versions added too much startup cost.  */
129 #if defined (HAVE_SYS_SDT_H) && defined (STAP_PROBE2) && _SDT_NOTE_TYPE >= 3
130   STAP_PROBE2 (libgcc, unwind, cfa, handler);
131 #else
132   asm ("");
133 #endif
136 /* This is a wrapper to be called when we need to restore core registers.
137    It will call `_Unwind_DebugHook' before restoring the registers, thus
138    making it possible to intercept and debug exceptions.
140    When calling `_Unwind_DebugHook', the first argument (the CFA) is zero
141    because we are not interested in it.  However, it must be there (even
142    being zero) because GDB expects to find it when using the probe.  */
144 #define uw_restore_core_regs(TARGET, CORE)                                    \
145   do                                                                          \
146     {                                                                         \
147       void *handler = __builtin_frob_return_addr ((void *) VRS_PC (TARGET));  \
148       _Unwind_DebugHook (0, handler);                                         \
149       restore_core_regs (CORE);                                               \
150     }                                                                         \
151   while (0)
153 /* Perform a binary search for RETURN_ADDRESS in TABLE.  The table contains
154    NREC entries.  */
156 static const __EIT_entry *
157 search_EIT_table (const __EIT_entry * table, int nrec, _uw return_address)
159   _uw next_fn;
160   _uw this_fn;
161   int n, left, right;
163   if (nrec == 0)
164     return (__EIT_entry *) 0;
166   left = 0;
167   right = nrec - 1;
169   while (1)
170     {
171       n = (left + right) / 2;
172       this_fn = selfrel_offset31 (&table[n].fnoffset);
173       if (n != nrec - 1)
174         next_fn = selfrel_offset31 (&table[n + 1].fnoffset) - 1;
175       else
176         next_fn = (_uw)0 - 1;
178       if (return_address < this_fn)
179         {
180           if (n == left)
181             return (__EIT_entry *) 0;
182           right = n - 1;
183         }
184       else if (return_address <= next_fn)
185         return &table[n];
186       else
187         left = n + 1;
188     }
191 /* Find the exception index table eintry for the given address.
192    Fill in the relevant fields of the UCB.
193    Returns _URC_FAILURE if an error occurred, _URC_OK on success.  */
195 static _Unwind_Reason_Code
196 get_eit_entry (_Unwind_Control_Block *ucbp, _uw return_address)
198   const __EIT_entry * eitp;
199   int nrec;
200   
201   /* The return address is the address of the instruction following the
202      call instruction (plus one in thumb mode).  If this was the last
203      instruction in the function the address will lie in the following
204      function.  Subtract 2 from the address so that it points within the call
205      instruction itself.  */
206   return_address -= 2;
208   if (__gnu_Unwind_Find_exidx)
209     {
210       eitp = (const __EIT_entry *) __gnu_Unwind_Find_exidx (return_address,
211                                                             &nrec);
212       if (!eitp)
213         {
214           UCB_PR_ADDR (ucbp) = 0;
215           return _URC_FAILURE;
216         }
217     }
218   else
219     {
220       eitp = &__exidx_start;
221       nrec = &__exidx_end - &__exidx_start;
222     }
224   eitp = search_EIT_table (eitp, nrec, return_address);
226   if (!eitp)
227     {
228       UCB_PR_ADDR (ucbp) = 0;
229       return _URC_FAILURE;
230     }
231   ucbp->pr_cache.fnstart = selfrel_offset31 (&eitp->fnoffset);
233   /* Can this frame be unwound at all?  */
234   if (eitp->content == EXIDX_CANTUNWIND)
235     {
236       UCB_PR_ADDR (ucbp) = 0;
237       return _URC_END_OF_STACK;
238     }
240   /* Obtain the address of the "real" __EHT_Header word.  */
242   if (eitp->content & uint32_highbit)
243     {
244       /* It is immediate data.  */
245       ucbp->pr_cache.ehtp = (_Unwind_EHT_Header *)&eitp->content;
246       ucbp->pr_cache.additional = 1;
247     }
248   else
249     {
250       /* The low 31 bits of the content field are a self-relative
251          offset to an _Unwind_EHT_Entry structure.  */
252       ucbp->pr_cache.ehtp =
253         (_Unwind_EHT_Header *) selfrel_offset31 (&eitp->content);
254       ucbp->pr_cache.additional = 0;
255     }
257   /* Discover the personality routine address.  */
258   if (*ucbp->pr_cache.ehtp & (1u << 31))
259     {
260       /* One of the predefined standard routines.  */
261       _uw idx = (*(_uw *) ucbp->pr_cache.ehtp >> 24) & 0xf;
262       UCB_PR_ADDR (ucbp) = __gnu_unwind_get_pr_addr (idx);
263       if (UCB_PR_ADDR (ucbp) == 0)
264         {
265           /* Failed */
266           return _URC_FAILURE;
267         }
268     } 
269   else
270     {
271       /* Execute region offset to PR */
272       UCB_PR_ADDR (ucbp) = selfrel_offset31 (ucbp->pr_cache.ehtp);
273     }
274   return _URC_OK;
278 /* Perform phase2 unwinding.  VRS is the initial virtual register state.  */
280 static void __attribute__((noreturn))
281 unwind_phase2 (_Unwind_Control_Block * ucbp, phase2_vrs * vrs)
283   _Unwind_Reason_Code pr_result;
285   do
286     {
287       /* Find the entry for this routine.  */
288       if (get_eit_entry (ucbp, VRS_PC(vrs)) != _URC_OK)
289         abort ();
291       UCB_SAVED_CALLSITE_ADDR (ucbp) = VRS_PC(vrs);
293       /* Call the pr to decide what to do.  */
294       pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
295         (_US_UNWIND_FRAME_STARTING, ucbp, (_Unwind_Context *) vrs);
296     }
297   while (pr_result == _URC_CONTINUE_UNWIND);
298   
299   if (pr_result != _URC_INSTALL_CONTEXT)
300     abort();
302   uw_restore_core_regs (vrs, &vrs->core);
305 /* Perform phase2 forced unwinding.  */
307 static _Unwind_Reason_Code
308 unwind_phase2_forced (_Unwind_Control_Block *ucbp, phase2_vrs *entry_vrs,
309                       int resuming)
311   _Unwind_Stop_Fn stop_fn = (_Unwind_Stop_Fn) UCB_FORCED_STOP_FN (ucbp);
312   void *stop_arg = (void *)UCB_FORCED_STOP_ARG (ucbp);
313   _Unwind_Reason_Code pr_result = 0;
314   /* We use phase1_vrs here even though we do not demand save, for the
315      prev_sp field.  */
316   phase1_vrs saved_vrs, next_vrs;
318   /* Save the core registers.  */
319   saved_vrs.core = entry_vrs->core;
320   /* We don't need to demand-save the non-core registers, because we
321      unwind in a single pass.  */
322   saved_vrs.demand_save_flags = 0;
324   /* Unwind until we reach a propagation barrier.  */
325   do
326     {
327       _Unwind_State action;
328       _Unwind_Reason_Code entry_code;
329       _Unwind_Reason_Code stop_code;
331       /* Find the entry for this routine.  */
332       entry_code = get_eit_entry (ucbp, VRS_PC (&saved_vrs));
334       if (resuming)
335         {
336           action = _US_UNWIND_FRAME_RESUME | _US_FORCE_UNWIND;
337           resuming = 0;
338         }
339       else
340         action = _US_UNWIND_FRAME_STARTING | _US_FORCE_UNWIND;
342       if (entry_code == _URC_OK)
343         {
344           UCB_SAVED_CALLSITE_ADDR (ucbp) = VRS_PC (&saved_vrs);
346           next_vrs = saved_vrs;
348           /* Call the pr to decide what to do.  */
349           pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
350             (action, ucbp, (void *) &next_vrs);
352           saved_vrs.prev_sp = VRS_SP (&next_vrs);
353         }
354       else
355         {
356           /* Treat any failure as the end of unwinding, to cope more
357              gracefully with missing EH information.  Mixed EH and
358              non-EH within one object will usually result in failure,
359              because the .ARM.exidx tables do not indicate the end
360              of the code to which they apply; but mixed EH and non-EH
361              shared objects should return an unwind failure at the
362              entry of a non-EH shared object.  */
363           action |= _US_END_OF_STACK;
365           saved_vrs.prev_sp = VRS_SP (&saved_vrs);
366         }
368       stop_code = stop_fn (1, action, ucbp->exception_class, ucbp,
369                            (void *)&saved_vrs, stop_arg);
370       if (stop_code != _URC_NO_REASON)
371         return _URC_FAILURE;
373       if (entry_code != _URC_OK)
374         return entry_code;
376       saved_vrs = next_vrs;
377     }
378   while (pr_result == _URC_CONTINUE_UNWIND);
380   if (pr_result != _URC_INSTALL_CONTEXT)
381     {
382       /* Some sort of failure has occurred in the pr and probably the
383          pr returned _URC_FAILURE.  */
384       return _URC_FAILURE;
385     }
387   uw_restore_core_regs (&saved_vrs, &saved_vrs.core);
390 /* This is a very limited implementation of _Unwind_GetCFA.  It returns
391    the stack pointer as it is about to be unwound, and is only valid
392    while calling the stop function during forced unwinding.  If the
393    current personality routine result is going to run a cleanup, this
394    will not be the CFA; but when the frame is really unwound, it will
395    be.  */
397 _Unwind_Word
398 _Unwind_GetCFA (_Unwind_Context *context)
400   return ((phase1_vrs *) context)->prev_sp;
403 /* Perform phase1 unwinding.  UCBP is the exception being thrown, and
404    entry_VRS is the register state on entry to _Unwind_RaiseException.  */
406 _Unwind_Reason_Code
407 __gnu_Unwind_RaiseException (_Unwind_Control_Block *, phase2_vrs *);
409 _Unwind_Reason_Code
410 __gnu_Unwind_RaiseException (_Unwind_Control_Block * ucbp,
411                              phase2_vrs * entry_vrs)
413   phase1_vrs saved_vrs;
414   _Unwind_Reason_Code pr_result;
416   /* Set the pc to the call site.  */
417   VRS_PC (entry_vrs) = VRS_RETURN(entry_vrs);
419   /* Save the core registers.  */
420   saved_vrs.core = entry_vrs->core;
421   /* Set demand-save flags.  */
422   saved_vrs.demand_save_flags = ~(_uw) 0;
423   
424   /* Unwind until we reach a propagation barrier.  */
425   do
426     {
427       /* Find the entry for this routine.  */
428       if (get_eit_entry (ucbp, VRS_PC (&saved_vrs)) != _URC_OK)
429         return _URC_FAILURE;
431       /* Call the pr to decide what to do.  */
432       pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
433         (_US_VIRTUAL_UNWIND_FRAME, ucbp, (void *) &saved_vrs);
434     }
435   while (pr_result == _URC_CONTINUE_UNWIND);
437   /* We've unwound as far as we want to go, so restore the original
438      register state.  */
439   restore_non_core_regs (&saved_vrs);
440   if (pr_result != _URC_HANDLER_FOUND)
441     {
442       /* Some sort of failure has occurred in the pr and probably the
443          pr returned _URC_FAILURE.  */
444       return _URC_FAILURE;
445     }
446   
447   unwind_phase2 (ucbp, entry_vrs);
450 /* Resume unwinding after a cleanup has been run.  UCBP is the exception
451    being thrown and ENTRY_VRS is the register state on entry to
452    _Unwind_Resume.  */
453 _Unwind_Reason_Code
454 __gnu_Unwind_ForcedUnwind (_Unwind_Control_Block *,
455                            _Unwind_Stop_Fn, void *, phase2_vrs *);
457 _Unwind_Reason_Code
458 __gnu_Unwind_ForcedUnwind (_Unwind_Control_Block *ucbp,
459                            _Unwind_Stop_Fn stop_fn, void *stop_arg,
460                            phase2_vrs *entry_vrs)
462   UCB_FORCED_STOP_FN (ucbp) = (_uw) stop_fn;
463   UCB_FORCED_STOP_ARG (ucbp) = (_uw) stop_arg;
465   /* Set the pc to the call site.  */
466   VRS_PC (entry_vrs) = VRS_RETURN(entry_vrs);
468   return unwind_phase2_forced (ucbp, entry_vrs, 0);
471 _Unwind_Reason_Code
472 __gnu_Unwind_Resume (_Unwind_Control_Block *, phase2_vrs *);
474 _Unwind_Reason_Code
475 __gnu_Unwind_Resume (_Unwind_Control_Block * ucbp, phase2_vrs * entry_vrs)
477   _Unwind_Reason_Code pr_result;
479   /* Recover the saved address.  */
480   VRS_PC (entry_vrs) = UCB_SAVED_CALLSITE_ADDR (ucbp);
482   if (UCB_FORCED_STOP_FN (ucbp))
483     {
484       unwind_phase2_forced (ucbp, entry_vrs, 1);
486       /* We can't return failure at this point.  */
487       abort ();
488     }
490   /* Call the cached PR.  */
491   pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
492         (_US_UNWIND_FRAME_RESUME, ucbp, (_Unwind_Context *) entry_vrs);
494   switch (pr_result)
495     {
496     case _URC_INSTALL_CONTEXT:
497       /* Upload the registers to enter the landing pad.  */
498       uw_restore_core_regs (entry_vrs, &entry_vrs->core);
500     case _URC_CONTINUE_UNWIND:
501       /* Continue unwinding the next frame.  */
502       unwind_phase2 (ucbp, entry_vrs);
504     default:
505       abort ();
506     }
509 _Unwind_Reason_Code
510 __gnu_Unwind_Resume_or_Rethrow (_Unwind_Control_Block *, phase2_vrs *);
512 _Unwind_Reason_Code
513 __gnu_Unwind_Resume_or_Rethrow (_Unwind_Control_Block * ucbp,
514                                 phase2_vrs * entry_vrs)
516   if (!UCB_FORCED_STOP_FN (ucbp))
517     return __gnu_Unwind_RaiseException (ucbp, entry_vrs);
519   /* Set the pc to the call site.  */
520   VRS_PC (entry_vrs) = VRS_RETURN (entry_vrs);
521   /* Continue unwinding the next frame.  */
522   return unwind_phase2_forced (ucbp, entry_vrs, 0);
525 /* Clean up an exception object when unwinding is complete.  */
526 void
527 _Unwind_Complete (_Unwind_Control_Block * ucbp __attribute__((unused)))
532 /* Free an exception.  */
534 void
535 _Unwind_DeleteException (_Unwind_Exception * exc)
537   if (exc->exception_cleanup)
538     (*exc->exception_cleanup) (_URC_FOREIGN_EXCEPTION_CAUGHT, exc);
542 /* Perform stack backtrace through unwind data.  */
543 _Unwind_Reason_Code
544 __gnu_Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument,
545                        phase2_vrs * entry_vrs);
546 _Unwind_Reason_Code
547 __gnu_Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument,
548                        phase2_vrs * entry_vrs)
550   phase1_vrs saved_vrs;
551   _Unwind_Reason_Code code;
553   _Unwind_Control_Block ucb;
554   _Unwind_Control_Block *ucbp = &ucb;
556   /* Set the pc to the call site.  */
557   VRS_PC (entry_vrs) = VRS_RETURN (entry_vrs);
559   /* Save the core registers.  */
560   saved_vrs.core = entry_vrs->core;
561   /* Set demand-save flags.  */
562   saved_vrs.demand_save_flags = ~(_uw) 0;
563   
564   do
565     {
566       /* Find the entry for this routine.  */
567       if (get_eit_entry (ucbp, VRS_PC (&saved_vrs)) != _URC_OK)
568         {
569           code = _URC_FAILURE;
570           break;
571         }
573       /* The dwarf unwinder assumes the context structure holds things
574          like the function and LSDA pointers.  The ARM implementation
575          caches these in the exception header (UCB).  To avoid
576          rewriting everything we make the virtual IP register point at
577          the UCB.  */
578       _Unwind_SetGR((_Unwind_Context *)&saved_vrs, UNWIND_POINTER_REG, (_Unwind_Ptr) ucbp);
580       /* Call trace function.  */
581       if ((*trace) ((_Unwind_Context *) &saved_vrs, trace_argument) 
582           != _URC_NO_REASON)
583         {
584           code = _URC_FAILURE;
585           break;
586         }
588       /* Call the pr to decide what to do.  */
589       code = ((personality_routine) UCB_PR_ADDR (ucbp))
590         (_US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND, 
591          ucbp, (void *) &saved_vrs);
592     }
593   while (code != _URC_END_OF_STACK
594          && code != _URC_FAILURE);
596   restore_non_core_regs (&saved_vrs);
597   return code;
601 /* Common implementation for ARM ABI defined personality routines.
602    ID is the index of the personality routine, other arguments are as defined
603    by __aeabi_unwind_cpp_pr{0,1,2}.  */
605 static _Unwind_Reason_Code
606 __gnu_unwind_pr_common (_Unwind_State state,
607                         _Unwind_Control_Block *ucbp,
608                         _Unwind_Context *context,
609                         int id)
611   __gnu_unwind_state uws;
612   _uw *data;
613   _uw offset;
614   _uw len;
615   _uw rtti_count;
616   int phase2_call_unexpected_after_unwind = 0;
617   int in_range = 0;
618   int forced_unwind = state & _US_FORCE_UNWIND;
620   state &= _US_ACTION_MASK;
622   data = (_uw *) ucbp->pr_cache.ehtp;
623   uws.data = *(data++);
624   uws.next = data;
625   if (id == 0)
626     {
627       uws.data <<= 8;
628       uws.words_left = 0;
629       uws.bytes_left = 3;
630     }
631   else if (id < 3)
632     {
633       uws.words_left = (uws.data >> 16) & 0xff;
634       uws.data <<= 16;
635       uws.bytes_left = 2;
636       data += uws.words_left;
637     }
639   /* Restore the saved pointer.  */
640   if (state == _US_UNWIND_FRAME_RESUME)
641     data = (_uw *) ucbp->cleanup_cache.bitpattern[0];
643   if ((ucbp->pr_cache.additional & 1) == 0)
644     {
645       /* Process descriptors.  */
646       while (*data)
647         {
648           _uw addr;
649           _uw fnstart;
651           if (id == 2)
652             {
653               len = ((EHT32 *) data)->length;
654               offset = ((EHT32 *) data)->offset;
655               data += 2;
656             }
657           else
658             {
659               len = ((EHT16 *) data)->length;
660               offset = ((EHT16 *) data)->offset;
661               data++;
662             }
664           fnstart = ucbp->pr_cache.fnstart + (offset & ~1);
665           addr = _Unwind_GetGR (context, R_PC);
666           in_range = (fnstart <= addr && addr < fnstart + (len & ~1));
668           switch (((offset & 1) << 1) | (len & 1))
669             {
670             case 0:
671               /* Cleanup.  */
672               if (state != _US_VIRTUAL_UNWIND_FRAME
673                   && in_range)
674                 {
675                   /* Cleanup in range, and we are running cleanups.  */
676                   _uw lp;
678                   /* Landing pad address is 31-bit pc-relative offset.  */
679                   lp = selfrel_offset31 (data);
680                   data++;
681                   /* Save the exception data pointer.  */
682                   ucbp->cleanup_cache.bitpattern[0] = (_uw) data;
683                   if (!__cxa_begin_cleanup (ucbp))
684                     return _URC_FAILURE;
685                   /* Setup the VRS to enter the landing pad.  */
686                   _Unwind_SetGR (context, R_PC, lp);
687                   return _URC_INSTALL_CONTEXT;
688                 }
689               /* Cleanup not in range, or we are in stage 1.  */
690               data++;
691               break;
693             case 1:
694               /* Catch handler.  */
695               if (state == _US_VIRTUAL_UNWIND_FRAME)
696                 {
697                   if (in_range)
698                     {
699                       /* Check for a barrier.  */
700                       _uw rtti;
701                       bool is_reference = (data[0] & uint32_highbit) != 0;
702                       void *matched;
703                       enum __cxa_type_match_result match_type;
705                       /* Check for no-throw areas.  */
706                       if (data[1] == (_uw) -2)
707                         return _URC_FAILURE;
709                       /* The thrown object immediately follows the ECB.  */
710                       matched = (void *)(ucbp + 1);
711                       if (data[1] != (_uw) -1)
712                         {
713                           /* Match a catch specification.  */
714                           rtti = _Unwind_decode_typeinfo_ptr (0,
715                                                               (_uw) &data[1]);
716                           match_type = __cxa_type_match (ucbp,
717                                                          (type_info *) rtti,
718                                                          is_reference,
719                                                          &matched);
720                         }
721                       else
722                         match_type = ctm_succeeded;
724                       if (match_type)
725                         {
726                           ucbp->barrier_cache.sp =
727                             _Unwind_GetGR (context, R_SP);
728                           // ctm_succeeded_with_ptr_to_base really
729                           // means _c_t_m indirected the pointer
730                           // object.  We have to reconstruct the
731                           // additional pointer layer by using a temporary.
732                           if (match_type == ctm_succeeded_with_ptr_to_base)
733                             {
734                               ucbp->barrier_cache.bitpattern[2]
735                                 = (_uw) matched;
736                               ucbp->barrier_cache.bitpattern[0]
737                                 = (_uw) &ucbp->barrier_cache.bitpattern[2];
738                             }
739                           else
740                             ucbp->barrier_cache.bitpattern[0] = (_uw) matched;
741                           ucbp->barrier_cache.bitpattern[1] = (_uw) data;
742                           return _URC_HANDLER_FOUND;
743                         }
744                     }
745                   /* Handler out of range, or not matched.  */
746                 }
747               else if (ucbp->barrier_cache.sp == _Unwind_GetGR (context, R_SP)
748                        && ucbp->barrier_cache.bitpattern[1] == (_uw) data)
749                 {
750                   /* Matched a previous propagation barrier.  */
751                   _uw lp;
753                   /* Setup for entry to the handler.  */
754                   lp = selfrel_offset31 (data);
755                   _Unwind_SetGR (context, R_PC, lp);
756                   _Unwind_SetGR (context, 0, (_uw) ucbp);
757                   return _URC_INSTALL_CONTEXT;
758                 }
759               /* Catch handler not matched.  Advance to the next descriptor.  */
760               data += 2;
761               break;
763             case 2:
764               rtti_count = data[0] & 0x7fffffff;
765               /* Exception specification.  */
766               if (state == _US_VIRTUAL_UNWIND_FRAME)
767                 {
768                   if (in_range && (!forced_unwind || !rtti_count))
769                     {
770                       /* Match against the exception specification.  */
771                       _uw i;
772                       _uw rtti;
773                       void *matched;
775                       for (i = 0; i < rtti_count; i++)
776                         {
777                           matched = (void *)(ucbp + 1);
778                           rtti = _Unwind_decode_typeinfo_ptr (0,
779                               (_uw) &data[i + 1]);
780                           if (__cxa_type_match (ucbp, (type_info *) rtti, 0,
781                                                 &matched))
782                             break;
783                         }
785                       if (i == rtti_count)
786                         {
787                           /* Exception does not match the spec.  */
788                           ucbp->barrier_cache.sp =
789                             _Unwind_GetGR (context, R_SP);
790                           ucbp->barrier_cache.bitpattern[0] = (_uw) matched;
791                           ucbp->barrier_cache.bitpattern[1] = (_uw) data;
792                           return _URC_HANDLER_FOUND;
793                         }
794                     }
795                   /* Handler out of range, or exception is permitted.  */
796                 }
797               else if (ucbp->barrier_cache.sp == _Unwind_GetGR (context, R_SP)
798                        && ucbp->barrier_cache.bitpattern[1] == (_uw) data)
799                 {
800                   /* Matched a previous propagation barrier.  */
801                   _uw lp;
802                   /* Record the RTTI list for __cxa_call_unexpected.  */
803                   ucbp->barrier_cache.bitpattern[1] = rtti_count;
804                   ucbp->barrier_cache.bitpattern[2] = 0;
805                   ucbp->barrier_cache.bitpattern[3] = 4;
806                   ucbp->barrier_cache.bitpattern[4] = (_uw) &data[1];
808                   if (data[0] & uint32_highbit)
809                     {
810                       data += rtti_count + 1;
811                       /* Setup for entry to the handler.  */
812                       lp = selfrel_offset31 (data);
813                       data++;
814                       _Unwind_SetGR (context, R_PC, lp);
815                       _Unwind_SetGR (context, 0, (_uw) ucbp);
816                       return _URC_INSTALL_CONTEXT;
817                     }
818                   else
819                     phase2_call_unexpected_after_unwind = 1;
820                 }
821               if (data[0] & uint32_highbit)
822                 data++;
823               data += rtti_count + 1;
824               break;
826             default:
827               /* Should never happen.  */
828               return _URC_FAILURE;
829             }
830           /* Finished processing this descriptor.  */
831         }
832     }
834   if (id >= 3)
835     {
836       /* 24-bit ecoding */
837       if (__gnu_unwind_24bit (context, uws.data, id == 4) != _URC_OK)
838         return _URC_FAILURE;
839     }
840   else
841     {
842       if (__gnu_unwind_execute (context, &uws) != _URC_OK)
843         return _URC_FAILURE;
844     }
845     
846   if (phase2_call_unexpected_after_unwind)
847     {
848       /* Enter __cxa_unexpected as if called from the call site.  */
849       _Unwind_SetGR (context, R_LR, _Unwind_GetGR (context, R_PC));
850       _Unwind_SetGR (context, R_PC, (_uw) &__cxa_call_unexpected);
851       return _URC_INSTALL_CONTEXT;
852     }
854   return _URC_CONTINUE_UNWIND;