Exemple #1
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;
}
Exemple #2
0
/* producer function to add a prologue unat_gr descriptor */
__unw_error_t unwind_info_add_prologue_unat_gr_info(__unw_info_t *info, __uint32_t gr) {
	__unw_error_t ret = __UNW_OK;
	__unw_format_p3_t desc;
	__uint64_t rsize;

	/* 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_gr descriptor */
	/* format P3 */
	/* 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 */
	/* 1 0 1 1 0 0 1 0 0 gr            */
	if (gr >= 128) {
		return __UNW_INV_ARG_ERROR;
	}
	desc._fix[0] = 0xb2;
	desc._fix[1] = 0x00;
	desc._fix[1] |= gr;
	rsize = 2;

	/* add descriptor */
	ret = unwind_info_add_desc(rsize, (char *)&desc);

	return ret;
}
Exemple #3
0
/* producer function to add a prologue fr_mem descriptor */
__unw_error_t unwind_info_add_prologue_fr_mem_info(__unw_info_t *info,
								__uint32_t frmask) {
	__unw_error_t ret = __UNW_OK;
	__unw_format_p6_t desc;
	__uint64_t rsize;

	/* 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 fr_mem descriptor */
	/* format P6 */
	/* 7 6 5 4 3 2 1 0 */ 
	/* 1 1 0 0 frmask  */
	if (frmask >= 16) {
		return __UNW_INV_ARG_ERROR;
	}
	desc._fix[0] = 0xc0;
	desc._fix[0] |= frmask;
	rsize = 1;

	/* add descriptor */
	ret = unwind_info_add_desc(rsize, (char *)&desc);

	return ret;
}
Exemple #4
0
/* producer function to add a prologue frgr_mem descriptor */
__unw_error_t unwind_info_add_prologue_frgr_mem_info(__unw_info_t *info,
					__uint32_t grmask, __uint32_t frmask) {
	__unw_error_t ret = __UNW_OK;
	__unw_format_p5_t desc;
	__uint64_t rsize;

	/* 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 frgr_mem descriptor */
	/* format P5 */
	/* 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 */ 
	/* 1 0 1 1 1 0 0 0 grmask  frmask                                */
	if ((grmask >= 16) || (frmask >= 1048576)) {
		return __UNW_INV_ARG_ERROR;
	}
	desc._fix[0] = 0xb9;
	desc._fix[1] = (grmask << 4);
	desc._fix[1] |= ((frmask & 0xf0000) >> 16);
	desc._fix[2] = ((frmask & 0x0ff00) >> 8);
	desc._fix[3] = (frmask & 0x000ff);
	rsize = 4;

	/* add descriptor */
	ret = unwind_info_add_desc(rsize, (char *)&desc);

	return ret;
}
Exemple #5
0
/* producer function to add a prologue br_gr descriptor */
__unw_error_t unwind_info_add_prologue_br_gr_info(__unw_info_t *info,
						__uint32_t brmask, __uint32_t gr) {
	__unw_error_t ret = __UNW_OK;
	__unw_format_p2_t desc;
	__uint64_t rsize;

	/* 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 br_gr descriptor */
	/* format P2 */
	/* 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 */ 
	/* 1 0 1 0 brmask    gr            */
	if ((brmask >= 32) || (gr >= 128)) {
		return __UNW_INV_ARG_ERROR;
	}
	desc._fix[0] = 0xa0;
	desc._fix[0] |= ((brmask & 0x1e) >> 1);
	desc._fix[1] = 0x00;
	desc._fix[1] |= ((brmask & 0x01) << 7);
	desc._fix[1] |= gr;
	rsize = 2;

	/* add descriptor */
	ret = unwind_info_add_desc(rsize, (char *)&desc);

	return ret;
}
Exemple #6
0
/* producer function to add a prologue spill_mask descriptor */
__unw_error_t unwind_info_add_prologue_spill_mask_info(__unw_info_t *info,
						void *ptr, __uint64_t size) {
	__unw_error_t ret;
	char type[1];

	/* check valid info argument */
	if (NULL == info) {
		return __UNW_NULL_ERROR;
	} else if (_unwind_info + _unwind_info_size != info) {
		return __UNW_INV_ARG_ERROR;
	}

	/* add descriptor */
	type[0] = 0xb8;
	ret = unwind_info_add_desc(1, type);
	if (ret != __UNW_OK) {
		return ret;
	}
	return unwind_info_add_desc(size, (char *)ptr);
}
Exemple #7
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;
}
Exemple #8
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;
}
Exemple #9
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;
}