Exemplo n.º 1
0
/* 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, &reg);
	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;
}
Exemplo n.º 2
0
/* 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;
}
Exemplo n.º 3
0
/* 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, &reg);
	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;
}
Exemplo n.º 4
0
/* 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;
}