static void __TI_unwind_frame(_Unwind_Exception *uexcep, _Unwind_Context *context) { _Unwind_Reason_Code reason_code; /*-----------------------------------------------------------------------*/ /* Start Phase 2 unwinding, will unwind frames till we find a handler */ /* that needs to be run. */ /*-----------------------------------------------------------------------*/ while (1) { /*-------------------------------------------------------------------*/ /* Look up Unwind Table using PC to find the EHT, set up PR to call */ /*-------------------------------------------------------------------*/ _UINT32 v_pc = __TI_targ_regbuf_get_pc(context); if (find_et_setup_pr(uexcep, v_pc) != _URC_SUCCESS) abort(); /*-------------------------------------------------------------------*/ /* Save regbuf PC, it will be overwritten by PR */ /*-------------------------------------------------------------------*/ uexcep->unwinder_data.saved_callsite_addr = v_pc; #ifdef DEBUG_UNWINDER printf("UW: saved PC: %"PRIx32"\n", v_pc); #endif /*-------------------------------------------------------------------*/ /* Call PR with phase set to Phase2 Start */ /*-------------------------------------------------------------------*/ #pragma diag_suppress 1107 reason_code = ((_PR_TYPE)(uexcep->unwinder_data.pr_addr))(_UP_Phase2_Start, uexcep, context); #pragma diag_default 1107 #ifdef DEBUG_UNWINDER printf("UW: PR returned to __TI_unwind_frame\n"); #endif if (reason_code != _URC_CONTINUE_UNWIND) break; } if (reason_code != _URC_INSTALL_CONTEXT) abort(); /*-----------------------------------------------------------------------*/ /* Copy register buffer regs into machine regs, results in call to */ /* handler set up by the PR */ /*-----------------------------------------------------------------------*/ __TI_targ_regbuf_install(context); }
_Unwind_Reason_Code __TI_Unwind_RaiseException2(_Unwind_Exception *uexcep, _Unwind_Context *ph1_context, _Unwind_Context *ph2_context) { #ifdef DEBUG_UNWINDER printf("UW: In __TI_Unwind_RaiseException2, UE @ %p, ph1_context @ %p, ph2_context @ %p\n", uexcep, ph1_context, ph2_context); #endif /*-----------------------------------------------------------------------*/ /* Search for a handler */ /*-----------------------------------------------------------------------*/ _Unwind_Reason_Code reason_code; while (1) { /*-------------------------------------------------------------------*/ /* Look up Unwind Table using PC to find the EHT, set up PR to call */ /*-------------------------------------------------------------------*/ if (find_et_setup_pr(uexcep, __TI_targ_regbuf_get_pc(ph1_context)) != _URC_SUCCESS) { #ifdef DEBUG_UNWINDER printf("UW: find_et_setup_pr() != _URC_SUCCESS\n"); #endif return _URC_FATAL_PHASE1_ERROR; } /*-------------------------------------------------------------------*/ /* Call PR with phase set to Phase1 */ /*-------------------------------------------------------------------*/ #pragma diag_suppress 1107 reason_code = ((_PR_TYPE)(uexcep->unwinder_data.pr_addr))(_UP_Phase1, uexcep, ph1_context); #pragma diag_default 1107 #ifdef DEBUG_UNWINDER printf("UW: PR returned to __TI_Unwind_RaiseException\n"); #endif if (reason_code != _URC_CONTINUE_UNWIND) break; } #ifdef DEBUG_UNWINDER printf("UW: Unwind phase 1 finished\n"); #endif /*-----------------------------------------------------------------------*/ /* At this point, we should have found a handler for the exception */ /*-----------------------------------------------------------------------*/ if (reason_code != _URC_HANDLER_FOUND) return _URC_FATAL_PHASE1_ERROR; /*-----------------------------------------------------------------------*/ /* Start phase 2 unwinding */ /*-----------------------------------------------------------------------*/ __TI_unwind_frame(uexcep, ph2_context); /*-----------------------------------------------------------------------*/ /* Should not get here, if we do, indicate failure */ /*-----------------------------------------------------------------------*/ return _URC_FATAL_PHASE2_ERROR; }
_Unwind_Reason_Code __TI_Unwind_RaiseException(_Unwind_Exception *uexcep, _Unwind_Context *context) { #ifdef DEBUG_UNWINDER printf("UW: In __TI_Unwind_RaiseException, UE @ %p, context @ %p\n", uexcep, context); #endif /*-----------------------------------------------------------------------*/ /* Call target specific routine to make a copy of the register context */ /* for use by the Phase 1 unwinder. This needs to be a copy because */ /* we're going to simulate unwinding by writing to it, and we don't want */ /* to scribble on the original yet. Phase 2 will use the original, */ /* since at that time we are committed to unwinding the frame. */ /*-----------------------------------------------------------------------*/ _Unwind_Context *ph1_context = __TI_targ_unwind_regbuf_setup(uexcep, context); if (!ph1_context) { #ifdef DEBUG_UNWINDER printf("UW: __TI_targ_unwind_regbuf_setup() == NULL\n"); #endif return _URC_FAILURE; } /*-----------------------------------------------------------------------*/ /* Search for a handler */ /*-----------------------------------------------------------------------*/ _Unwind_Reason_Code reason_code; while (1) { /*-------------------------------------------------------------------*/ /* Look up Unwind Table using PC to find the EHT, set up PR to call */ /*-------------------------------------------------------------------*/ if (find_et_setup_pr(uexcep, __TI_targ_regbuf_get_pc(ph1_context)) != _URC_SUCCESS) { #ifdef DEBUG_UNWINDER printf("UW: find_et_setup_pr() != _URC_SUCCESS\n"); #endif return _URC_FATAL_PHASE1_ERROR; } /*-------------------------------------------------------------------*/ /* Call PR with phase set to Phase1 */ /*-------------------------------------------------------------------*/ #pragma diag_suppress 1107 reason_code = ((_PR_TYPE)(uexcep->unwinder_data.pr_addr))(_UP_Phase1, uexcep, ph1_context); #pragma diag_default 1107 #ifdef DEBUG_UNWINDER printf("UW: PR returned to __TI_Unwind_RaiseException\n"); #endif if (reason_code != _URC_CONTINUE_UNWIND) break; } #ifdef DEBUG_UNWINDER printf("UW: Unwind phase 1 finished\n"); #endif /*-----------------------------------------------------------------------*/ /* Phase 1 Register Context no longer required, free it */ /*-----------------------------------------------------------------------*/ free(ph1_context); /*-----------------------------------------------------------------------*/ /* At this point, we should have found a handler for the exception */ /*-----------------------------------------------------------------------*/ if (reason_code != _URC_HANDLER_FOUND) return _URC_FATAL_PHASE1_ERROR; /*-----------------------------------------------------------------------*/ /* Start phase 2 unwinding */ /*-----------------------------------------------------------------------*/ __TI_unwind_frame(uexcep, context); /*-----------------------------------------------------------------------*/ /* Should not get here, if we do, indicate failure */ /*-----------------------------------------------------------------------*/ return _URC_FATAL_PHASE2_ERROR; }