/* producer function to add a spill_sprel descriptor */ __unw_error_t unwind_info_add_spill_sprel_info (__unw_info_t *info, __uint64_t when, __UNW_REG_TYPE ureg, __uint64_t offset) { __unw_error_t ret = __UNW_OK; __uint64_t rsize, esize1, esize2; __uint8_t a, b, reg; char encoded[2+(2*__UNW_ENCODING_SIZE)]; /* check valid info argument */ if (NULL == info) { return __UNW_NULL_ERROR; } else if (_unwind_info + _unwind_info_size != info) { return __UNW_INV_ARG_ERROR; } /* check valid time argument */ if (_current_region_total_size > 0 && when >= _current_region_total_size) { return __UNW_INV_SIZE_ERROR; } /* construct and add the spill_offset descriptor */ /* format X1 */ /* 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 */ /* 1 1 1 1 1 0 0 1 r a b reg t(LEB128) spoff(ULEB128) */ /* r = 1 */ encoded[0] = 0xf9; reg_enum_to_abreg(ureg, &a, &b, ®); encoded[1] = 0x80; encoded[1] |= (a << 6); encoded[1] |= (b << 5); encoded[1] |= reg; if ((esize1 = __leb128_encode((char *)&encoded[2], (__uint64_t)__UNW_ENCODING_SIZE, when)) == 0) { return __UNW_INTERNAL_ERROR; } if ((esize2 = __leb128_encode((char *)&encoded[2+esize1], (__uint64_t)__UNW_ENCODING_SIZE, offset)) == 0) { return __UNW_INTERNAL_ERROR; } rsize = 2 + esize1 + esize2; /* add descriptor */ ret = unwind_info_add_desc(rsize, (char*) &encoded); return ret; }
/* producer function to add a prologue unat_sprel descriptor */ __unw_error_t unwind_info_add_prologue_unat_sprel_info(__unw_info_t *info, __uint64_t offset) { __unw_error_t ret = __UNW_OK; __unw_format_p8_t *desc; __uint64_t rsize, esize; char encoded[2+__UNW_ENCODING_SIZE]; /* check valid info argument */ if (NULL == info) { return __UNW_NULL_ERROR; } else if (_unwind_info + _unwind_info_size != info) { return __UNW_INV_ARG_ERROR; } /* construct and add the unat_sprel descriptor */ /* format P8 */ /* 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 */ /* 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 1 spoff(LEB128) */ encoded[0] = 0xf0; encoded[1] = 0x05; if ((esize = __leb128_encode((char *)&encoded[2], (__uint64_t)__UNW_ENCODING_SIZE, offset)) == 0) { return __UNW_INTERNAL_ERROR; } desc = (__unw_format_p8_t *)&encoded; rsize = 2 + esize; /* add descriptor */ ret = unwind_info_add_desc(rsize, (char *)desc); return ret; }
/* producer function to add a spill_reg descriptor */ __unw_error_t unwind_info_add_spill_reg_to_gr_info (__unw_info_t *info, __uint64_t when, __UNW_REG_TYPE ureg, __uint32_t treg) { __unw_error_t ret = __UNW_OK; __uint64_t rsize, esize; __uint8_t a, b, reg; char encoded[3+1*__UNW_ENCODING_SIZE]; /* check valid info argument */ if (NULL == info) { return __UNW_NULL_ERROR; } else if (_unwind_info + _unwind_info_size != info) { return __UNW_INV_ARG_ERROR; } /* check valid time argument */ if (_current_region_total_size > 0 && when >= _current_region_total_size) { return __UNW_INV_SIZE_ERROR; } /* construct and add the spill_reg descriptor */ /* format X2 */ /* 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 */ /* 1 1 1 1 1 0 1 0 x a b reg y treg t(LEB128) */ /* x = 0, y = 0 */ encoded[0] = 0xfa; reg_enum_to_abreg(ureg, &a, &b, ®); encoded[1] = 0; encoded[1] |= (a << 6); encoded[1] |= (b << 5); encoded[1] |= reg; encoded[2] = 0x0; encoded[2] |= treg; if ((esize = __leb128_encode((char *)&encoded[3], (__uint64_t)__UNW_ENCODING_SIZE, when)) == 0) { return __UNW_INTERNAL_ERROR; } rsize = 3 + esize; /* add descriptor */ ret = unwind_info_add_desc(rsize, (char*) &encoded); return ret; }
/* producer function to add a prologue bsp_when descriptor */ __unw_error_t unwind_info_add_prologue_bsp_when_info(__unw_info_t *info, __uint64_t when) { __unw_error_t ret = __UNW_OK; __unw_format_p8_t *desc; __uint64_t rsize, esize; char encoded[2+__UNW_ENCODING_SIZE]; /* check valid info argument */ if (NULL == info) { return __UNW_NULL_ERROR; } else if (_unwind_info + _unwind_info_size != info) { return __UNW_INV_ARG_ERROR; } /* check valid time argument */ if (when >= _current_region_total_size) { return __UNW_INV_SIZE_ERROR; } /* construct and add the bsp_when descriptor */ /* format P8 */ /* 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 */ /* 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 t(LEB128) */ encoded[0] = 0xf0; encoded[1] = 0x07; if ((esize = __leb128_encode((char *)&encoded[2], (__uint64_t)__UNW_ENCODING_SIZE, when)) == 0) { return __UNW_INTERNAL_ERROR; } desc = (__unw_format_p8_t *)&encoded; rsize = 2 + esize; /* add descriptor */ ret = unwind_info_add_desc(rsize, (char *)desc); return ret; }