00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "unwind.h"
00029
00030
00031
00032 extern void abort (void);
00033
00034
00035
00036 typedef unsigned char bool;
00037
00038 typedef struct _ZSt9type_info type_info;
00039
00040 void __attribute__((weak)) __cxa_call_unexpected(_Unwind_Control_Block *ucbp);
00041 bool __attribute__((weak)) __cxa_begin_cleanup(_Unwind_Control_Block *ucbp);
00042 bool __attribute__((weak)) __cxa_type_match(_Unwind_Control_Block *ucbp,
00043 const type_info *rttip,
00044 void **matched_object);
00045
00046 _Unwind_Ptr __attribute__((weak))
00047 __gnu_Unwind_Find_exidx (_Unwind_Ptr, int *);
00048
00049
00050 #define R_IP 12
00051 #define R_SP 13
00052 #define R_LR 14
00053 #define R_PC 15
00054
00055 #define EXIDX_CANTUNWIND 1
00056 #define uint32_highbit (((_uw) 1) << 31)
00057
00058 #define UCB_FORCED_STOP_FN(ucbp) ((ucbp)->unwinder_cache.reserved1)
00059 #define UCB_PR_ADDR(ucbp) ((ucbp)->unwinder_cache.reserved2)
00060 #define UCB_SAVED_CALLSITE_ADDR(ucbp) ((ucbp)->unwinder_cache.reserved3)
00061 #define UCB_FORCED_STOP_ARG(ucbp) ((ucbp)->unwinder_cache.reserved4)
00062
00063 struct core_regs
00064 {
00065 _uw r[16];
00066 };
00067
00068
00069
00070 struct vfp_regs
00071 {
00072 _uw64 d[16];
00073 _uw pad;
00074 };
00075
00076 struct fpa_reg
00077 {
00078 _uw w[3];
00079 };
00080
00081 struct fpa_regs
00082 {
00083 struct fpa_reg f[8];
00084 };
00085
00086
00087
00088 typedef struct
00089 {
00090 _uw16 length;
00091 _uw16 offset;
00092 } EHT16;
00093
00094 typedef struct
00095 {
00096 _uw length;
00097 _uw offset;
00098 } EHT32;
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 typedef struct
00110 {
00111
00112 _uw demand_save_flags;
00113 struct core_regs core;
00114 _uw prev_sp;
00115 struct vfp_regs vfp;
00116 struct fpa_regs fpa;
00117 } phase1_vrs;
00118
00119 #define DEMAND_SAVE_VFP 1
00120
00121
00122 typedef struct
00123 {
00124 _uw demand_save_flags;
00125 struct core_regs core;
00126 } phase2_vrs;
00127
00128
00129
00130
00131 typedef struct __EIT_entry
00132 {
00133 _uw fnoffset;
00134 _uw content;
00135 } __EIT_entry;
00136
00137
00138
00139
00140 void __attribute__((noreturn)) restore_core_regs (struct core_regs *);
00141
00142
00143
00144
00145 void __gnu_Unwind_Save_VFP (struct vfp_regs * p);
00146 void __gnu_Unwind_Restore_VFP (struct vfp_regs * p);
00147
00148
00149 static void
00150 restore_non_core_regs (phase1_vrs * vrs)
00151 {
00152 if ((vrs->demand_save_flags & DEMAND_SAVE_VFP) == 0)
00153 __gnu_Unwind_Restore_VFP (&vrs->vfp);
00154 }
00155
00156
00157
00158
00159 extern int __text_start;
00160 extern int __data_start;
00161
00162
00163 extern __EIT_entry __exidx_start;
00164 extern __EIT_entry __exidx_end;
00165
00166
00167 extern _Unwind_Reason_Code __aeabi_unwind_cpp_pr0 (_Unwind_State,
00168 _Unwind_Control_Block *, _Unwind_Context *);
00169 extern _Unwind_Reason_Code __aeabi_unwind_cpp_pr1 (_Unwind_State,
00170 _Unwind_Control_Block *, _Unwind_Context *) __attribute__((weak));
00171 extern _Unwind_Reason_Code __aeabi_unwind_cpp_pr2 (_Unwind_State,
00172 _Unwind_Control_Block *, _Unwind_Context *) __attribute__((weak));
00173
00174
00175
00176 _Unwind_VRS_Result _Unwind_VRS_Get (_Unwind_Context *context,
00177 _Unwind_VRS_RegClass regclass,
00178 _uw regno,
00179 _Unwind_VRS_DataRepresentation representation,
00180 void *valuep)
00181 {
00182 phase1_vrs *vrs = (phase1_vrs *) context;
00183
00184 switch (regclass)
00185 {
00186 case _UVRSC_CORE:
00187 if (representation != _UVRSD_UINT32
00188 || regno > 15)
00189 return _UVRSR_FAILED;
00190 *(_uw *) valuep = vrs->core.r[regno];
00191 return _UVRSR_OK;
00192
00193 case _UVRSC_VFP:
00194 case _UVRSC_FPA:
00195 case _UVRSC_WMMXD:
00196 case _UVRSC_WMMXC:
00197 return _UVRSR_NOT_IMPLEMENTED;
00198
00199 default:
00200 return _UVRSR_FAILED;
00201 }
00202 }
00203
00204
00205
00206
00207 _Unwind_VRS_Result _Unwind_VRS_Set (_Unwind_Context *context,
00208 _Unwind_VRS_RegClass regclass,
00209 _uw regno,
00210 _Unwind_VRS_DataRepresentation representation,
00211 void *valuep)
00212 {
00213 phase1_vrs *vrs = (phase1_vrs *) context;
00214
00215 switch (regclass)
00216 {
00217 case _UVRSC_CORE:
00218 if (representation != _UVRSD_UINT32
00219 || regno > 15)
00220 return _UVRSR_FAILED;
00221
00222 vrs->core.r[regno] = *(_uw *) valuep;
00223 return _UVRSR_OK;
00224
00225 case _UVRSC_VFP:
00226 case _UVRSC_FPA:
00227 case _UVRSC_WMMXD:
00228 case _UVRSC_WMMXC:
00229 return _UVRSR_NOT_IMPLEMENTED;
00230
00231 default:
00232 return _UVRSR_FAILED;
00233 }
00234 }
00235
00236
00237
00238
00239 _Unwind_VRS_Result _Unwind_VRS_Pop (_Unwind_Context *context,
00240 _Unwind_VRS_RegClass regclass,
00241 _uw discriminator,
00242 _Unwind_VRS_DataRepresentation representation)
00243 {
00244 phase1_vrs *vrs = (phase1_vrs *) context;
00245
00246 switch (regclass)
00247 {
00248 case _UVRSC_CORE:
00249 {
00250 _uw *ptr;
00251 _uw mask;
00252 int i;
00253
00254 if (representation != _UVRSD_UINT32)
00255 return _UVRSR_FAILED;
00256
00257 mask = discriminator & 0xffff;
00258 ptr = (_uw *) vrs->core.r[R_SP];
00259
00260 for (i = 0; i < 16; i++)
00261 {
00262 if (mask & (1 << i))
00263 vrs->core.r[i] = *(ptr++);
00264 }
00265
00266 if ((mask & (1 << R_SP)) == 0)
00267 vrs->core.r[R_SP] = (_uw) ptr;
00268 }
00269 return _UVRSR_OK;
00270
00271 case _UVRSC_VFP:
00272 {
00273 _uw start = discriminator >> 16;
00274 _uw count = discriminator & 0xffff;
00275 struct vfp_regs tmp;
00276 _uw *sp;
00277 _uw *dest;
00278
00279 if ((representation != _UVRSD_VFPX && representation != _UVRSD_DOUBLE)
00280 || start + count > 16)
00281 return _UVRSR_FAILED;
00282
00283 if (vrs->demand_save_flags & DEMAND_SAVE_VFP)
00284 {
00285
00286 vrs->demand_save_flags &= ~DEMAND_SAVE_VFP;
00287 __gnu_Unwind_Save_VFP (&vrs->vfp);
00288 }
00289
00290
00291
00292
00293
00294 __gnu_Unwind_Save_VFP (&tmp);
00295
00296
00297
00298 sp = (_uw *) vrs->core.r[R_SP];
00299 dest = (_uw *) &tmp.d[start];
00300 count *= 2;
00301 while (count--)
00302 *(dest++) = *(sp++);
00303
00304
00305 if (representation == _UVRSD_VFPX)
00306 sp++;
00307
00308
00309 vrs->core.r[R_SP] = (_uw) sp;
00310
00311
00312 __gnu_Unwind_Restore_VFP (&tmp);
00313 }
00314 return _UVRSR_OK;
00315
00316 case _UVRSC_FPA:
00317 case _UVRSC_WMMXD:
00318 case _UVRSC_WMMXC:
00319 return _UVRSR_NOT_IMPLEMENTED;
00320
00321 default:
00322 return _UVRSR_FAILED;
00323 }
00324 }
00325
00326
00327
00328
00329
00330
00331 static inline _uw
00332 selfrel_offset31 (const _uw *p)
00333 {
00334 _uw offset;
00335
00336 offset = *p;
00337
00338 if (offset & (1 << 30))
00339 offset |= 1u << 31;
00340 else
00341 offset &= ~(1u << 31);
00342
00343 return offset + (_uw) p;
00344 }
00345
00346
00347
00348
00349
00350 static const __EIT_entry *
00351 search_EIT_table (const __EIT_entry * table, int nrec, _uw return_address)
00352 {
00353 _uw next_fn;
00354 _uw this_fn;
00355 int n, left, right;
00356
00357 if (nrec == 0)
00358 return (__EIT_entry *) 0;
00359
00360 left = 0;
00361 right = nrec - 1;
00362
00363 while (1)
00364 {
00365 n = (left + right) / 2;
00366 this_fn = selfrel_offset31 (&table[n].fnoffset);
00367 if (n != nrec - 1)
00368 next_fn = selfrel_offset31 (&table[n + 1].fnoffset) - 1;
00369 else
00370 next_fn = (_uw)0 - 1;
00371
00372 if (return_address < this_fn)
00373 {
00374 if (n == left)
00375 return (__EIT_entry *) 0;
00376 right = n - 1;
00377 }
00378 else if (return_address <= next_fn)
00379 return &table[n];
00380 else
00381 left = n + 1;
00382 }
00383 }
00384
00385
00386
00387
00388
00389 static _Unwind_Reason_Code
00390 get_eit_entry (_Unwind_Control_Block *ucbp, _uw return_address)
00391 {
00392 const __EIT_entry * eitp;
00393 int nrec;
00394
00395
00396
00397
00398
00399
00400 return_address -= 2;
00401
00402 if (__gnu_Unwind_Find_exidx)
00403 {
00404 eitp = (const __EIT_entry *) __gnu_Unwind_Find_exidx (return_address,
00405 &nrec);
00406 if (!eitp)
00407 {
00408 UCB_PR_ADDR (ucbp) = 0;
00409 return _URC_FAILURE;
00410 }
00411 }
00412 else
00413 {
00414 eitp = &__exidx_start;
00415 nrec = &__exidx_end - &__exidx_start;
00416 }
00417
00418 eitp = search_EIT_table (eitp, nrec, return_address);
00419
00420 if (!eitp)
00421 {
00422 UCB_PR_ADDR (ucbp) = 0;
00423 return _URC_FAILURE;
00424 }
00425 ucbp->pr_cache.fnstart = selfrel_offset31 (&eitp->fnoffset);
00426
00427
00428 if (eitp->content == EXIDX_CANTUNWIND)
00429 {
00430 UCB_PR_ADDR (ucbp) = 0;
00431 return _URC_END_OF_STACK;
00432 }
00433
00434
00435
00436 if (eitp->content & uint32_highbit)
00437 {
00438
00439 ucbp->pr_cache.ehtp = (_Unwind_EHT_Header *)&eitp->content;
00440 ucbp->pr_cache.additional = 1;
00441 }
00442 else
00443 {
00444
00445
00446 ucbp->pr_cache.ehtp =
00447 (_Unwind_EHT_Header *) selfrel_offset31 (&eitp->content);
00448 ucbp->pr_cache.additional = 0;
00449 }
00450
00451
00452 if (*ucbp->pr_cache.ehtp & (1u << 31))
00453 {
00454
00455 _uw idx = (*(_uw *) ucbp->pr_cache.ehtp >> 24) & 0xf;
00456 if (idx == 0)
00457 UCB_PR_ADDR (ucbp) = (_uw) &__aeabi_unwind_cpp_pr0;
00458 else if (idx == 1)
00459 UCB_PR_ADDR (ucbp) = (_uw) &__aeabi_unwind_cpp_pr1;
00460 else if (idx == 2)
00461 UCB_PR_ADDR (ucbp) = (_uw) &__aeabi_unwind_cpp_pr2;
00462 else
00463 {
00464 UCB_PR_ADDR (ucbp) = 0;
00465 return _URC_FAILURE;
00466 }
00467 }
00468 else
00469 {
00470
00471 UCB_PR_ADDR (ucbp) = selfrel_offset31 (ucbp->pr_cache.ehtp);
00472 }
00473 return _URC_OK;
00474 }
00475
00476
00477
00478
00479 static void __attribute__((noreturn))
00480 unwind_phase2 (_Unwind_Control_Block * ucbp, phase2_vrs * vrs)
00481 {
00482 _Unwind_Reason_Code pr_result;
00483
00484 do
00485 {
00486
00487 if (get_eit_entry (ucbp, vrs->core.r[R_PC]) != _URC_OK)
00488 abort ();
00489
00490 UCB_SAVED_CALLSITE_ADDR (ucbp) = vrs->core.r[R_PC];
00491
00492
00493 pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
00494 (_US_UNWIND_FRAME_STARTING, ucbp, (_Unwind_Context *) vrs);
00495 }
00496 while (pr_result == _URC_CONTINUE_UNWIND);
00497
00498 if (pr_result != _URC_INSTALL_CONTEXT)
00499 abort();
00500
00501 restore_core_regs (&vrs->core);
00502 }
00503
00504
00505
00506 static _Unwind_Reason_Code
00507 unwind_phase2_forced (_Unwind_Control_Block *ucbp, phase2_vrs *entry_vrs,
00508 int resuming)
00509 {
00510 _Unwind_Stop_Fn stop_fn = (_Unwind_Stop_Fn) UCB_FORCED_STOP_FN (ucbp);
00511 void *stop_arg = (void *)UCB_FORCED_STOP_ARG (ucbp);
00512 _Unwind_Reason_Code pr_result = 0;
00513
00514
00515 phase1_vrs saved_vrs, next_vrs;
00516
00517
00518 saved_vrs.core = entry_vrs->core;
00519
00520
00521 saved_vrs.demand_save_flags = 0;
00522
00523
00524 do
00525 {
00526 _Unwind_State action;
00527 _Unwind_Reason_Code entry_code;
00528 _Unwind_Reason_Code stop_code;
00529
00530
00531 entry_code = get_eit_entry (ucbp, saved_vrs.core.r[R_PC]);
00532
00533 if (resuming)
00534 {
00535 action = _US_UNWIND_FRAME_RESUME | _US_FORCE_UNWIND;
00536 resuming = 0;
00537 }
00538 else
00539 action = _US_UNWIND_FRAME_STARTING | _US_FORCE_UNWIND;
00540
00541 if (entry_code == _URC_OK)
00542 {
00543 UCB_SAVED_CALLSITE_ADDR (ucbp) = saved_vrs.core.r[R_PC];
00544
00545 next_vrs = saved_vrs;
00546
00547
00548 pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
00549 (action, ucbp, (void *) &next_vrs);
00550
00551 saved_vrs.prev_sp = next_vrs.core.r[R_SP];
00552 }
00553 else
00554 {
00555
00556
00557
00558
00559
00560
00561
00562 action |= _US_END_OF_STACK;
00563
00564 saved_vrs.prev_sp = saved_vrs.core.r[R_SP];
00565 }
00566
00567 stop_code = stop_fn (1, action, ucbp->exception_class, ucbp,
00568 (void *)&saved_vrs, stop_arg);
00569 if (stop_code != _URC_NO_REASON)
00570 return _URC_FAILURE;
00571
00572 if (entry_code != _URC_OK)
00573 return entry_code;
00574
00575 saved_vrs = next_vrs;
00576 }
00577 while (pr_result == _URC_CONTINUE_UNWIND);
00578
00579 if (pr_result != _URC_INSTALL_CONTEXT)
00580 {
00581
00582
00583 return _URC_FAILURE;
00584 }
00585
00586 restore_core_regs (&saved_vrs.core);
00587 }
00588
00589
00590
00591
00592
00593
00594
00595
00596 _Unwind_Word
00597 _Unwind_GetCFA (_Unwind_Context *context)
00598 {
00599 return ((phase1_vrs *) context)->prev_sp;
00600 }
00601
00602
00603
00604
00605 _Unwind_Reason_Code
00606 __gnu_Unwind_RaiseException (_Unwind_Control_Block *, phase2_vrs *);
00607
00608 _Unwind_Reason_Code
00609 __gnu_Unwind_RaiseException (_Unwind_Control_Block * ucbp,
00610 phase2_vrs * entry_vrs)
00611 {
00612 phase1_vrs saved_vrs;
00613 _Unwind_Reason_Code pr_result;
00614
00615
00616 entry_vrs->core.r[R_PC] = entry_vrs->core.r[R_LR];
00617
00618
00619 saved_vrs.core = entry_vrs->core;
00620
00621 saved_vrs.demand_save_flags = ~(_uw) 0;
00622
00623
00624 do
00625 {
00626
00627 if (get_eit_entry (ucbp, saved_vrs.core.r[R_PC]) != _URC_OK)
00628 return _URC_FAILURE;
00629
00630
00631 pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
00632 (_US_VIRTUAL_UNWIND_FRAME, ucbp, (void *) &saved_vrs);
00633 }
00634 while (pr_result == _URC_CONTINUE_UNWIND);
00635
00636
00637
00638 restore_non_core_regs (&saved_vrs);
00639 if (pr_result != _URC_HANDLER_FOUND)
00640 {
00641
00642
00643 return _URC_FAILURE;
00644 }
00645
00646 unwind_phase2 (ucbp, entry_vrs);
00647 }
00648
00649
00650
00651
00652 _Unwind_Reason_Code
00653 __gnu_Unwind_ForcedUnwind (_Unwind_Control_Block *,
00654 _Unwind_Stop_Fn, void *, phase2_vrs *);
00655
00656 _Unwind_Reason_Code
00657 __gnu_Unwind_ForcedUnwind (_Unwind_Control_Block *ucbp,
00658 _Unwind_Stop_Fn stop_fn, void *stop_arg,
00659 phase2_vrs *entry_vrs)
00660 {
00661 UCB_FORCED_STOP_FN (ucbp) = (_uw) stop_fn;
00662 UCB_FORCED_STOP_ARG (ucbp) = (_uw) stop_arg;
00663
00664
00665 entry_vrs->core.r[R_PC] = entry_vrs->core.r[R_LR];
00666
00667 return unwind_phase2_forced (ucbp, entry_vrs, 0);
00668 }
00669
00670 _Unwind_Reason_Code
00671 __gnu_Unwind_Resume (_Unwind_Control_Block *, phase2_vrs *);
00672
00673 _Unwind_Reason_Code
00674 __gnu_Unwind_Resume (_Unwind_Control_Block * ucbp, phase2_vrs * entry_vrs)
00675 {
00676 _Unwind_Reason_Code pr_result;
00677
00678
00679 entry_vrs->core.r[R_PC] = UCB_SAVED_CALLSITE_ADDR (ucbp);
00680
00681 if (UCB_FORCED_STOP_FN (ucbp))
00682 {
00683 unwind_phase2_forced (ucbp, entry_vrs, 1);
00684
00685
00686 abort ();
00687 }
00688
00689
00690 pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
00691 (_US_UNWIND_FRAME_RESUME, ucbp, (_Unwind_Context *) entry_vrs);
00692
00693 switch (pr_result)
00694 {
00695 case _URC_INSTALL_CONTEXT:
00696
00697 restore_core_regs (&entry_vrs->core);
00698
00699 case _URC_CONTINUE_UNWIND:
00700
00701 unwind_phase2 (ucbp, entry_vrs);
00702
00703 default:
00704 abort ();
00705 }
00706 }
00707
00708 _Unwind_Reason_Code
00709 __gnu_Unwind_Resume_or_Rethrow (_Unwind_Control_Block *, phase2_vrs *);
00710
00711 _Unwind_Reason_Code
00712 __gnu_Unwind_Resume_or_Rethrow (_Unwind_Control_Block * ucbp,
00713 phase2_vrs * entry_vrs)
00714 {
00715 if (!UCB_FORCED_STOP_FN (ucbp))
00716 return __gnu_Unwind_RaiseException (ucbp, entry_vrs);
00717
00718
00719 entry_vrs->core.r[R_PC] = entry_vrs->core.r[R_LR];
00720
00721 return unwind_phase2_forced (ucbp, entry_vrs, 0);
00722 }
00723
00724
00725 void
00726 _Unwind_Complete (_Unwind_Control_Block * ucbp __attribute__((unused)))
00727 {
00728 }
00729
00730
00731
00732
00733 static inline _Unwind_Control_Block *
00734 unwind_UCB_from_context (_Unwind_Context * context)
00735 {
00736 return (_Unwind_Control_Block *) _Unwind_GetGR (context, R_IP);
00737 }
00738
00739
00740
00741
00742 void
00743 _Unwind_DeleteException (_Unwind_Exception * exc)
00744 {
00745 if (exc->exception_cleanup)
00746 (*exc->exception_cleanup) (_URC_FOREIGN_EXCEPTION_CAUGHT, exc);
00747 }
00748
00749
00750
00751
00752
00753
00754 static _Unwind_Reason_Code
00755 __gnu_unwind_pr_common (_Unwind_State state,
00756 _Unwind_Control_Block *ucbp,
00757 _Unwind_Context *context,
00758 int id)
00759 {
00760 __gnu_unwind_state uws;
00761 _uw *data;
00762 _uw offset;
00763 _uw len;
00764 _uw rtti_count;
00765 int phase2_call_unexpected_after_unwind = 0;
00766 int in_range = 0;
00767 int forced_unwind = state & _US_FORCE_UNWIND;
00768
00769 state &= _US_ACTION_MASK;
00770
00771 data = (_uw *) ucbp->pr_cache.ehtp;
00772 uws.data = *(data++);
00773 uws.next = data;
00774 if (id == 0)
00775 {
00776 uws.data <<= 8;
00777 uws.words_left = 0;
00778 uws.bytes_left = 3;
00779 }
00780 else
00781 {
00782 uws.words_left = (uws.data >> 16) & 0xff;
00783 uws.data <<= 16;
00784 uws.bytes_left = 2;
00785 data += uws.words_left;
00786 }
00787
00788
00789 if (state == _US_UNWIND_FRAME_RESUME)
00790 data = (_uw *) ucbp->cleanup_cache.bitpattern[0];
00791
00792 if ((ucbp->pr_cache.additional & 1) == 0)
00793 {
00794
00795 while (*data)
00796 {
00797 _uw addr;
00798 _uw fnstart;
00799
00800 if (id == 2)
00801 {
00802 len = ((EHT32 *) data)->length;
00803 offset = ((EHT32 *) data)->offset;
00804 data += 2;
00805 }
00806 else
00807 {
00808 len = ((EHT16 *) data)->length;
00809 offset = ((EHT16 *) data)->offset;
00810 data++;
00811 }
00812
00813 fnstart = ucbp->pr_cache.fnstart + (offset & ~1);
00814 addr = _Unwind_GetGR (context, R_PC);
00815 in_range = (fnstart <= addr && addr < fnstart + (len & ~1));
00816
00817 switch (((offset & 1) << 1) | (len & 1))
00818 {
00819 case 0:
00820
00821 if (state != _US_VIRTUAL_UNWIND_FRAME
00822 && in_range)
00823 {
00824
00825 _uw lp;
00826
00827
00828 lp = selfrel_offset31 (data);
00829 data++;
00830
00831 ucbp->cleanup_cache.bitpattern[0] = (_uw) data;
00832 if (!__cxa_begin_cleanup (ucbp))
00833 return _URC_FAILURE;
00834
00835 _Unwind_SetGR (context, R_PC, lp);
00836 return _URC_INSTALL_CONTEXT;
00837 }
00838
00839 data++;
00840 break;
00841
00842 case 1:
00843
00844 if (state == _US_VIRTUAL_UNWIND_FRAME)
00845 {
00846 if (in_range)
00847 {
00848
00849 _uw rtti;
00850 void *matched;
00851
00852
00853 if (data[1] == (_uw) -2)
00854 return _URC_FAILURE;
00855
00856
00857 matched = (void *)(ucbp + 1);
00858 if (data[1] != (_uw) -1)
00859 {
00860
00861 rtti = _Unwind_decode_target2 ((_uw) &data[1]);
00862 if (!__cxa_type_match (ucbp, (type_info *) rtti,
00863 &matched))
00864 matched = (void *)0;
00865 }
00866
00867 if (matched)
00868 {
00869 ucbp->barrier_cache.sp =
00870 _Unwind_GetGR (context, R_SP);
00871 ucbp->barrier_cache.bitpattern[0] = (_uw) matched;
00872 ucbp->barrier_cache.bitpattern[1] = (_uw) data;
00873 return _URC_HANDLER_FOUND;
00874 }
00875 }
00876
00877 }
00878 else if (ucbp->barrier_cache.sp == _Unwind_GetGR (context, R_SP)
00879 && ucbp->barrier_cache.bitpattern[1] == (_uw) data)
00880 {
00881
00882 _uw lp;
00883
00884
00885 lp = selfrel_offset31 (data);
00886 _Unwind_SetGR (context, R_PC, lp);
00887 _Unwind_SetGR (context, 0, (_uw) ucbp);
00888 return _URC_INSTALL_CONTEXT;
00889 }
00890
00891 data += 2;
00892 break;
00893
00894 case 2:
00895 rtti_count = data[0] & 0x7fffffff;
00896
00897 if (state == _US_VIRTUAL_UNWIND_FRAME)
00898 {
00899 if (in_range && (!forced_unwind || !rtti_count))
00900 {
00901
00902 _uw i;
00903 _uw rtti;
00904 void *matched;
00905
00906 for (i = 0; i < rtti_count; i++)
00907 {
00908 matched = (void *)(ucbp + 1);
00909 rtti = _Unwind_decode_target2 ((_uw) &data[i + 1]);
00910 if (__cxa_type_match (ucbp, (type_info *) rtti,
00911 &matched))
00912 break;
00913 }
00914
00915 if (i == rtti_count)
00916 {
00917
00918 ucbp->barrier_cache.sp =
00919 _Unwind_GetGR (context, R_SP);
00920 ucbp->barrier_cache.bitpattern[0] = (_uw) matched;
00921 ucbp->barrier_cache.bitpattern[1] = (_uw) data;
00922 return _URC_HANDLER_FOUND;
00923 }
00924 }
00925
00926 }
00927 else if (ucbp->barrier_cache.sp == _Unwind_GetGR (context, R_SP)
00928 && ucbp->barrier_cache.bitpattern[1] == (_uw) data)
00929 {
00930
00931 _uw lp;
00932
00933 ucbp->barrier_cache.bitpattern[1] = rtti_count;
00934 ucbp->barrier_cache.bitpattern[2] = 0;
00935 ucbp->barrier_cache.bitpattern[3] = 4;
00936 ucbp->barrier_cache.bitpattern[4] = (_uw) &data[1];
00937
00938 if (data[0] & uint32_highbit)
00939 phase2_call_unexpected_after_unwind = 1;
00940 else
00941 {
00942 data += rtti_count + 1;
00943
00944 lp = selfrel_offset31 (data);
00945 data++;
00946 _Unwind_SetGR (context, R_PC, lp);
00947 _Unwind_SetGR (context, 0, (_uw) ucbp);
00948 return _URC_INSTALL_CONTEXT;
00949 }
00950 }
00951 if (data[0] & uint32_highbit)
00952 data++;
00953 data += rtti_count + 1;
00954 break;
00955
00956 default:
00957
00958 return _URC_FAILURE;
00959 }
00960
00961 }
00962 }
00963
00964 if (__gnu_unwind_execute (context, &uws) != _URC_OK)
00965 return _URC_FAILURE;
00966
00967 if (phase2_call_unexpected_after_unwind)
00968 {
00969
00970 _Unwind_SetGR (context, R_LR, _Unwind_GetGR (context, R_PC));
00971 _Unwind_SetGR (context, R_PC, (_uw) &__cxa_call_unexpected);
00972 return _URC_INSTALL_CONTEXT;
00973 }
00974
00975 return _URC_CONTINUE_UNWIND;
00976 }
00977
00978
00979
00980
00981 _Unwind_Reason_Code
00982 __aeabi_unwind_cpp_pr0 (_Unwind_State state,
00983 _Unwind_Control_Block *ucbp,
00984 _Unwind_Context *context)
00985 {
00986 return __gnu_unwind_pr_common (state, ucbp, context, 0);
00987 }
00988
00989 _Unwind_Reason_Code
00990 __aeabi_unwind_cpp_pr1 (_Unwind_State state,
00991 _Unwind_Control_Block *ucbp,
00992 _Unwind_Context *context)
00993 {
00994 return __gnu_unwind_pr_common (state, ucbp, context, 1);
00995 }
00996
00997 _Unwind_Reason_Code
00998 __aeabi_unwind_cpp_pr2 (_Unwind_State state,
00999 _Unwind_Control_Block *ucbp,
01000 _Unwind_Context *context)
01001 {
01002 return __gnu_unwind_pr_common (state, ucbp, context, 2);
01003 }
01004
01005
01006 _Unwind_Ptr
01007 _Unwind_GetDataRelBase (_Unwind_Context *context __attribute__ ((unused)))
01008 {
01009 abort ();
01010 }
01011
01012 _Unwind_Ptr
01013 _Unwind_GetTextRelBase (_Unwind_Context *context __attribute__ ((unused)))
01014 {
01015 abort ();
01016 }