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