否则foreign exception caught by exception spec,记录信息并且返回
ttypeindex == 0, 表明cleanup为true
action中读取actionOffset
actionOffset为0,代表是action list的结尾
hasCleaup 并且是处于cleanup phase的话表示找到handler_found
否则是continue_unwind
前进到下一个action
找不到任何eh table entry来指定如何处理exception的情况下terminate
_Unwind_GetLanguageSpecificData
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/// Called by personality handler during phase 2 to get LSDA for current frame. _LIBUNWIND_EXPORT uintptr_t _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) { unw_cursor_t *cursor = (unw_cursor_t *)context; unw_proc_info_t frameInfo; uintptr_t result = 0; if (__unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS) result = (uintptr_t)frameInfo.lsda; _LIBUNWIND_TRACE_API( "_Unwind_GetLanguageSpecificData(context=%p) => 0x%llx", static_cast<void *>(context), (longlong)result); return result; }
unw_proc_info_t中包含了lsda的地址,直接读取并且返回
set_registers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
static void set_registers(_Unwind_Exception* unwind_exception, _Unwind_Context* context, const scan_results& results) { #if defined(__USING_SJLJ_EXCEPTIONS__) || defined(__USING_WASM_EXCEPTIONS__) #define __builtin_eh_return_data_regno(regno) regno #elif defined(__ibmxl__) // IBM xlclang++ compiler does not support __builtin_eh_return_data_regno. #define __builtin_eh_return_data_regno(regno) regno + 3 #endif _Unwind_SetGR(context, __builtin_eh_return_data_regno(0), reinterpret_cast<uintptr_t>(unwind_exception)); _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), static_cast<uintptr_t>(results.ttypeIndex)); _Unwind_SetIP(context, results.landingPad); }
/// Set value of specified register at cursor position in stack frame. _LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum, unw_word_t value) { _LIBUNWIND_TRACE_API("__unw_set_reg(cursor=%p, regNum=%d, value=0x%" PRIxPTR ")", static_cast<void *>(cursor), regNum, value); typedef LocalAddressSpace::pint_tpint_t; AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; if (co->validReg(regNum)) { co->setReg(regNum, (pint_t)value); // special case altering IP to re-find info (being called by personality // function) if (regNum == UNW_REG_IP) { unw_proc_info_t info; // First, get the FDE for the old location and then update it. co->getInfo(&info); co->setInfoBasedOnIPRegister(false); // If the original call expects stack adjustment, perform this now. // Normal frame unwinding would have included the offset already in the // CFA computation. // Note: for PA-RISC and other platforms where the stack grows up, // this should actually be - info.gp. LLVM doesn't currently support // any such platforms and Clang doesn't export a macro for them. if (info.gp) co->setReg(UNW_REG_SP, co->getReg(UNW_REG_SP) + info.gp); } return UNW_ESUCCESS; } return UNW_EBADREG; }