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
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/>. */
28 /* Used for SystemTap unwinder probe. */
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
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
60 ctm_succeeded_with_ptr_to_base = 2
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. */
95 /* An exception index table entry. */
97 typedef struct __EIT_entry
105 /* Only used in FDPIC case. */
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
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
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);
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) \
172 void *handler = __builtin_frob_return_addr ((void *) VRS_PC (TARGET)); \
173 _Unwind_DebugHook (0, handler); \
174 restore_core_regs (CORE); \
178 /* Perform a binary search for RETURN_ADDRESS in TABLE. The table contains
181 static const __EIT_entry *
182 search_EIT_table (const __EIT_entry * table, int nrec, _uw return_address)
189 return (__EIT_entry *) 0;
196 n = (left + right) / 2;
197 this_fn = selfrel_offset31 (&table[n].fnoffset);
199 next_fn = selfrel_offset31 (&table[n + 1].fnoffset) - 1;
201 next_fn = (_uw)0 - 1;
203 if (return_address < this_fn)
206 return (__EIT_entry *) 0;
209 else if (return_address <= next_fn)
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)
225 unsigned int funcdesc;
226 unsigned int handler;
227 unsigned int first_handler_instruction;
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
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
245 sp += ARM_UCONTEXT_SIGCONTEXT
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;
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;
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. */
272 if (__gnu_Unwind_Find_exidx)
274 eitp = (const __EIT_entry *) __gnu_Unwind_Find_exidx (return_address,
279 /* If we are unwinding a signal handler then perhaps we have
280 reached a trampoline. Try to detect jump to restorer
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))
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;
299 UCB_PR_ADDR (ucbp) = 0;
305 eitp = &__exidx_start;
306 nrec = &__exidx_end - &__exidx_start;
309 eitp = search_EIT_table (eitp, nrec, return_address);
314 /* If we are unwinding a signal handler then perhaps we have
315 reached a trampoline. Try to detect jump to restorer
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))
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;
334 UCB_PR_ADDR (ucbp) = 0;
337 ucbp->pr_cache.fnstart = selfrel_offset31 (&eitp->fnoffset);
339 /* Can this frame be unwound at all? */
340 if (eitp->content == EXIDX_CANTUNWIND)
343 /* If we are unwinding a signal handler then perhaps we have
344 reached a trampoline. Try to detect jump to restorer
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))
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;
363 UCB_PR_ADDR (ucbp) = 0;
364 return _URC_END_OF_STACK;
367 /* Obtain the address of the "real" __EHT_Header word. */
369 if (eitp->content & uint32_highbit)
371 /* It is immediate data. */
372 ucbp->pr_cache.ehtp = (_Unwind_EHT_Header *)&eitp->content;
373 ucbp->pr_cache.additional = 1;
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;
384 /* Discover the personality routine address. */
385 if (*ucbp->pr_cache.ehtp & (1u << 31))
387 /* One of the predefined standard routines. */
388 _uw idx = (*(_uw *) ucbp->pr_cache.ehtp >> 24) & 0xf;
391 struct funcdesc_t *funcdesc
392 = (struct funcdesc_t *) __gnu_unwind_get_pr_addr (idx);
395 UCB_PR_ADDR (ucbp) = funcdesc->ptr;
396 UCB_PR_GOT (ucbp) = funcdesc->got;
399 UCB_PR_ADDR (ucbp) = 0;
402 UCB_PR_ADDR (ucbp) = __gnu_unwind_get_pr_addr (idx);
404 if (UCB_PR_ADDR (ucbp) == 0)
412 /* Execute region offset to PR */
413 UCB_PR_ADDR (ucbp) = selfrel_offset31 (ucbp->pr_cache.ehtp);
416 = (unsigned int) _Unwind_gnu_Find_got ((_Unwind_Ptr) UCB_PR_ADDR (ucbp));
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;
432 /* Find the entry for this routine. */
433 if (get_eit_entry (ucbp, VRS_PC(vrs)) != _URC_OK)
436 UCB_SAVED_CALLSITE_ADDR (ucbp) = VRS_PC(vrs);
438 /* Call the pr to decide what to do. */
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);
448 pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
449 (_US_UNWIND_FRAME_STARTING, ucbp, (_Unwind_Context *) vrs);
452 while (pr_result == _URC_CONTINUE_UNWIND);
454 if (pr_result != _URC_INSTALL_CONTEXT)
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));
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,
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
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. */
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));
496 action = _US_UNWIND_FRAME_RESUME | _US_FORCE_UNWIND;
500 action = _US_UNWIND_FRAME_STARTING | _US_FORCE_UNWIND;
502 if (entry_code == _URC_OK)
504 UCB_SAVED_CALLSITE_ADDR (ucbp) = VRS_PC (&saved_vrs);
506 next_vrs = saved_vrs;
508 /* Call the pr to decide what to do. */
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);
518 pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
519 (action, ucbp, (void *) &next_vrs);
522 saved_vrs.prev_sp = VRS_SP (&next_vrs);
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);
538 stop_code = stop_fn (1, action, ucbp->exception_class, ucbp,
539 (void *)&saved_vrs, stop_arg);
540 if (stop_code != _URC_NO_REASON)
543 if (entry_code != _URC_OK)
546 saved_vrs = next_vrs;
548 while (pr_result == _URC_CONTINUE_UNWIND);
550 if (pr_result != _URC_INSTALL_CONTEXT)
552 /* Some sort of failure has occurred in the pr and probably the
553 pr returned _URC_FAILURE. */
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));
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
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. */
582 __gnu_Unwind_RaiseException (_Unwind_Control_Block *, phase2_vrs *);
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;
599 /* Unwind until we reach a propagation barrier. */
602 /* Find the entry for this routine. */
603 if (get_eit_entry (ucbp, VRS_PC (&saved_vrs)) != _URC_OK)
606 /* Call the pr to decide what to do. */
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);
616 pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
617 (_US_VIRTUAL_UNWIND_FRAME, ucbp, (void *) &saved_vrs);
620 while (pr_result == _URC_CONTINUE_UNWIND);
622 /* We've unwound as far as we want to go, so restore the original
624 restore_non_core_regs (&saved_vrs);
625 if (pr_result != _URC_HANDLER_FOUND)
627 /* Some sort of failure has occurred in the pr and probably the
628 pr returned _URC_FAILURE. */
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
639 __gnu_Unwind_ForcedUnwind (_Unwind_Control_Block *,
640 _Unwind_Stop_Fn, void *, phase2_vrs *);
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);
657 __gnu_Unwind_Resume (_Unwind_Control_Block *, phase2_vrs *);
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))
669 unwind_phase2_forced (ucbp, entry_vrs, 1);
671 /* We can't return failure at this point. */
675 /* Call the cached PR. */
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);
685 pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
686 (_US_UNWIND_FRAME_RESUME, ucbp, (_Unwind_Context *) entry_vrs);
691 case _URC_INSTALL_CONTEXT:
692 /* Upload the registers to enter the landing pad. */
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));
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);
709 __gnu_Unwind_Resume_or_Rethrow (_Unwind_Control_Block *, phase2_vrs *);
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. */
726 _Unwind_Complete (_Unwind_Control_Block * ucbp __attribute__((unused)))
731 /* Free an exception. */
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. */
743 __gnu_Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument,
744 phase2_vrs * entry_vrs);
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;
765 /* Find the entry for this routine. */
766 if (get_eit_entry (ucbp, VRS_PC (&saved_vrs)) != _URC_OK)
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
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)
787 /* Call the pr to decide what to do. */
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);
798 code = ((personality_routine) UCB_PR_ADDR (ucbp))
799 (_US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND,
800 ucbp, (void *) &saved_vrs);
803 while (code != _URC_END_OF_STACK
804 && code != _URC_FAILURE);
806 restore_non_core_regs (&saved_vrs);
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,
821 __gnu_unwind_state uws;
826 int phase2_call_unexpected_after_unwind = 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++);
843 uws.words_left = (uws.data >> 16) & 0xff;
846 data += uws.words_left;
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)
855 /* Process descriptors. */
863 len = ((EHT32 *) data)->length;
864 offset = ((EHT32 *) data)->offset;
869 len = ((EHT16 *) data)->length;
870 offset = ((EHT16 *) data)->offset;
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))
882 if (state != _US_VIRTUAL_UNWIND_FRAME
885 /* Cleanup in range, and we are running cleanups. */
888 /* Landing pad address is 31-bit pc-relative offset. */
889 lp = selfrel_offset31 (data);
891 /* Save the exception data pointer. */
892 ucbp->cleanup_cache.bitpattern[0] = (_uw) data;
893 if (!__cxa_begin_cleanup (ucbp))
895 /* Setup the VRS to enter the landing pad. */
896 _Unwind_SetGR (context, R_PC, lp);
897 return _URC_INSTALL_CONTEXT;
899 /* Cleanup not in range, or we are in stage 1. */
905 if (state == _US_VIRTUAL_UNWIND_FRAME)
909 /* Check for a barrier. */
911 bool is_reference = (data[0] & uint32_highbit) != 0;
913 enum __cxa_type_match_result match_type;
915 /* Check for no-throw areas. */
916 if (data[1] == (_uw) -2)
919 /* The thrown object immediately follows the ECB. */
920 matched = (void *)(ucbp + 1);
921 if (data[1] != (_uw) -1)
923 /* Match a catch specification. */
924 rtti = _Unwind_decode_typeinfo_ptr (0,
926 match_type = __cxa_type_match (ucbp,
932 match_type = ctm_succeeded;
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)
944 ucbp->barrier_cache.bitpattern[2]
946 ucbp->barrier_cache.bitpattern[0]
947 = (_uw) &ucbp->barrier_cache.bitpattern[2];
950 ucbp->barrier_cache.bitpattern[0] = (_uw) matched;
951 ucbp->barrier_cache.bitpattern[1] = (_uw) data;
952 return _URC_HANDLER_FOUND;
955 /* Handler out of range, or not matched. */
957 else if (ucbp->barrier_cache.sp == _Unwind_GetGR (context, R_SP)
958 && ucbp->barrier_cache.bitpattern[1] == (_uw) data)
960 /* Matched a previous propagation barrier. */
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;
969 /* Catch handler not matched. Advance to the next descriptor. */
974 rtti_count = data[0] & 0x7fffffff;
975 /* Exception specification. */
976 if (state == _US_VIRTUAL_UNWIND_FRAME)
978 if (in_range && (!forced_unwind || !rtti_count))
980 /* Match against the exception specification. */
985 for (i = 0; i < rtti_count; i++)
987 matched = (void *)(ucbp + 1);
988 rtti = _Unwind_decode_typeinfo_ptr (0,
990 if (__cxa_type_match (ucbp, (type_info *) rtti, 0,
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;
1005 /* Handler out of range, or exception is permitted. */
1007 else if (ucbp->barrier_cache.sp == _Unwind_GetGR (context, R_SP)
1008 && ucbp->barrier_cache.bitpattern[1] == (_uw) data)
1010 /* Matched a previous propagation barrier. */
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)
1020 data += rtti_count + 1;
1021 /* Setup for entry to the handler. */
1022 lp = selfrel_offset31 (data);
1024 _Unwind_SetGR (context, R_PC, lp);
1025 _Unwind_SetGR (context, 0, (_uw) ucbp);
1026 return _URC_INSTALL_CONTEXT;
1029 phase2_call_unexpected_after_unwind = 1;
1031 if (data[0] & uint32_highbit)
1033 data += rtti_count + 1;
1037 /* Should never happen. */
1038 return _URC_FAILURE;
1040 /* Finished processing this descriptor. */
1046 /* 24-bit ecoding */
1047 if (__gnu_unwind_24bit (context, uws.data, id == 4) != _URC_OK)
1048 return _URC_FAILURE;
1052 if (__gnu_unwind_execute (context, &uws) != _URC_OK)
1053 return _URC_FAILURE;
1056 if (phase2_call_unexpected_after_unwind)
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;
1064 return _URC_CONTINUE_UNWIND;