int
dwarf_attrval_string(Dwarf_Die die, Dwarf_Half attr, const char **strp, Dwarf_Error *err)
{
	Dwarf_Attribute at;
	Dwarf_Debug dbg;

	dbg = die != NULL ? die->die_dbg : NULL;

	if (die == NULL || strp == NULL) {
		DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	*strp = NULL;

	if ((at = _dwarf_attr_find(die, attr)) == NULL) {
		DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY);
		return (DW_DLV_NO_ENTRY);
	}

	switch (at->at_form) {
	case DW_FORM_strp:
		*strp = at->u[1].s;
		break;
	case DW_FORM_string:
		*strp = at->u[0].s;
		break;
	default:
		DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD);
		return (DW_DLV_ERROR);
	}

	return (DW_DLV_OK);
}
Exemple #2
0
int
dwarf_highpc_b(Dwarf_Die die, Dwarf_Addr *ret_highpc, Dwarf_Half *ret_form,
    enum Dwarf_Form_Class *ret_class, Dwarf_Error *error)
{
	Dwarf_Attribute at;
	Dwarf_Debug dbg;
	Dwarf_CU cu;

	dbg = die != NULL ? die->die_dbg : NULL;

	if (die == NULL || ret_highpc == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	if ((at = _dwarf_attr_find(die, DW_AT_high_pc)) == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
		return (DW_DLV_NO_ENTRY);
	}

	*ret_highpc = at->u[0].u64;

	if (ret_form != NULL) {
		*ret_form = at->at_form;
	}

	if (ret_class != NULL) {
		cu = die->die_cu;
		*ret_class = dwarf_get_form_class(cu->cu_version,
		    DW_AT_high_pc, cu->cu_length_size == 4 ? 4 : 8,
		    at->at_form);
	}

	return (DW_DLV_OK);
}
int
dwarf_attrval_flag(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *valp, Dwarf_Error *err)
{
	Dwarf_Attribute at;
	Dwarf_Debug dbg;

	dbg = die != NULL ? die->die_dbg : NULL;

	if (die == NULL || valp == NULL) {
		DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	*valp = 0;

	if ((at = _dwarf_attr_find(die, attr)) == NULL) {
		DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY);
		return (DW_DLV_NO_ENTRY);
	}

	switch (at->at_form) {
	case DW_FORM_flag:
		*valp = (Dwarf_Bool) (!!at->u[0].u64);
		break;
	default:
		DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD);
		return (DW_DLV_ERROR);
	}

	return (DW_DLV_OK);
}
Exemple #4
0
int
dwarf_hasattr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *ret_bool,
    Dwarf_Error *error)
{
	Dwarf_Debug dbg;

	dbg = die != NULL ? die->die_dbg : NULL;

	if (die == NULL || ret_bool == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	*ret_bool = (_dwarf_attr_find(die, attr) != NULL);

	return (DW_DLV_OK);
}
Exemple #5
0
int
dwarf_attrval_signed(Dwarf_Die die, Dwarf_Half attr, Dwarf_Signed *valp, Dwarf_Error *err)
{
	Dwarf_Attribute at;
	Dwarf_Debug dbg;

	dbg = die != NULL ? die->die_dbg : NULL;

	if (die == NULL || valp == NULL) {
		DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	*valp = 0;

	if ((at = _dwarf_attr_find(die, attr)) == NULL) {
		DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY);
		return (DW_DLV_NO_ENTRY);
	}

	switch (at->at_form) {
	case DW_FORM_data1:
		*valp = (int8_t) at->u[0].s64;
		break;
	case DW_FORM_data2:
		*valp = (int16_t) at->u[0].s64;
		break;
	case DW_FORM_data4:
		*valp = (int32_t) at->u[0].s64;
		break;
	case DW_FORM_data8:
	case DW_FORM_sdata:
		*valp = at->u[0].s64;
		break;
	default:
		DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD);
		return (DW_DLV_ERROR);
	}

	return (DW_DLV_OK);
}
Exemple #6
0
int
dwarf_arrayorder(Dwarf_Die die, Dwarf_Unsigned *ret_order, Dwarf_Error *error)
{
	Dwarf_Attribute at;
	Dwarf_Debug dbg;
	
	dbg = die != NULL ? die->die_dbg : NULL;

	if (die == NULL || ret_order == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	if ((at = _dwarf_attr_find(die, DW_AT_ordering)) == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
		return (DW_DLV_NO_ENTRY);
	}

	*ret_order = at->u[0].u64;

	return (DW_DLV_OK);
}
Exemple #7
0
int
dwarf_lowpc(Dwarf_Die die, Dwarf_Addr *ret_lowpc, Dwarf_Error *error)
{
	Dwarf_Attribute at;
	Dwarf_Debug dbg;

	dbg = die != NULL ? die->die_dbg : NULL;

	if (die == NULL || ret_lowpc == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	if ((at = _dwarf_attr_find(die, DW_AT_low_pc)) == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
		return (DW_DLV_NO_ENTRY);
	}

	*ret_lowpc = at->u[0].u64;

	return (DW_DLV_OK);
}
Exemple #8
0
int
dwarf_attr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Attribute *atp,
    Dwarf_Error *error)
{
	Dwarf_Debug dbg;
	Dwarf_Attribute at;

	dbg = die != NULL ? die->die_dbg : NULL;

	if (die == NULL || atp == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	if ((at = _dwarf_attr_find(die, attr)) == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
		return (DW_DLV_NO_ENTRY);
	}

	*atp = at;

	return (DW_DLV_OK);
}
int
dwarf_attrval_unsigned(Dwarf_Die die, Dwarf_Half attr, Dwarf_Unsigned *valp, Dwarf_Error *err)
{
	Dwarf_Attribute at;
	Dwarf_Die die1;
	Dwarf_Unsigned val;
	Dwarf_Debug dbg;

	dbg = die != NULL ? die->die_dbg : NULL;

	if (die == NULL || valp == NULL) {
		DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	*valp = 0;

	if ((at = _dwarf_attr_find(die, attr)) == NULL && attr != DW_AT_type) {
		DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY);
		return (DW_DLV_NO_ENTRY);
	}

	die1 = NULL;
	if (at == NULL &&
	    (at = _dwarf_attr_find(die, DW_AT_abstract_origin)) != NULL) {
		switch (at->at_form) {
		case DW_FORM_ref1:
		case DW_FORM_ref2:
		case DW_FORM_ref4:
		case DW_FORM_ref8:
		case DW_FORM_ref_udata:
			val = at->u[0].u64;
			if ((die1 = _dwarf_die_find(die, val)) == NULL ||
			    (at = _dwarf_attr_find(die1, attr)) == NULL) {
				if (die1 != NULL)
					dwarf_dealloc(dbg, die1, DW_DLA_DIE);
				DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY);
				return (DW_DLV_NO_ENTRY);
			}
			break;
		default:
			DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD);
			return (DW_DLV_ERROR);
		}
	}

	switch (at->at_form) {
	case DW_FORM_addr:
	case DW_FORM_data1:
	case DW_FORM_data2:
	case DW_FORM_data4:
	case DW_FORM_data8:
	case DW_FORM_udata:
	case DW_FORM_ref1:
	case DW_FORM_ref2:
	case DW_FORM_ref4:
	case DW_FORM_ref8:
	case DW_FORM_ref_udata:
		*valp = at->u[0].u64;
		break;
	default:
		if (die1 != NULL)
			dwarf_dealloc(dbg, die1, DW_DLA_DIE);
		DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD);
		return (DW_DLV_ERROR);
	}

	if (die1 != NULL)
		dwarf_dealloc(dbg, die1, DW_DLA_DIE);

	return (DW_DLV_OK);
}
int
dwarf_srcfiles(Dwarf_Die die, char ***srcfiles, Dwarf_Signed *srccount,
    Dwarf_Error *error)
{
	Dwarf_LineInfo li;
	Dwarf_LineFile lf;
	Dwarf_Debug dbg;
	Dwarf_CU cu;
	Dwarf_Attribute at; 
	int i;

	dbg = die != NULL ? die->die_dbg : NULL;

	if (die == NULL || srcfiles == NULL || srccount == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	if ((at = _dwarf_attr_find(die, DW_AT_stmt_list)) == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
		return (DW_DLV_NO_ENTRY);
	}

	cu = die->die_cu;
	if (cu->cu_lineinfo == NULL) {
		if (_dwarf_lineno_init(die, at->u[0].u64, error) !=
		    DW_DLE_NONE)
			return (DW_DLV_ERROR);
	}
	if (cu->cu_lineinfo == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
		return (DW_DLV_NO_ENTRY);
	}

	li = cu->cu_lineinfo;
	*srccount = (Dwarf_Signed) li->li_lflen;

	if (*srccount == 0) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
		return (DW_DLV_NO_ENTRY);
	}

	if (li->li_lfnarray != NULL) {
		*srcfiles = li->li_lfnarray;
		return (DW_DLV_OK);
	}

	if ((li->li_lfnarray = malloc(*srccount * sizeof(char *))) == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
		return (DW_DLV_ERROR);
	}

	for (i = 0, lf = STAILQ_FIRST(&li->li_lflist);
	     i < *srccount && lf != NULL; i++, lf = STAILQ_NEXT(lf, lf_next)) {
		if (lf->lf_fullpath)
			li->li_lfnarray[i] = lf->lf_fullpath;
		else
			li->li_lfnarray[i] = lf->lf_fname;
	}

	*srcfiles = li->li_lfnarray;

	return (DW_DLV_OK);
}
int
dwarf_srclines(Dwarf_Die die, Dwarf_Line **linebuf, Dwarf_Signed *linecount,
    Dwarf_Error *error)
{
	Dwarf_LineInfo li;
	Dwarf_Debug dbg;
	Dwarf_Line ln;
	Dwarf_CU cu;
	Dwarf_Attribute at; 
	int i;

	dbg = die != NULL ? die->die_dbg : NULL;

	if (die == NULL || linebuf == NULL || linecount == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	if ((at = _dwarf_attr_find(die, DW_AT_stmt_list)) == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
		return (DW_DLV_NO_ENTRY);
	}

	cu = die->die_cu;
	if (cu->cu_lineinfo == NULL) {
		if (_dwarf_lineno_init(die, at->u[0].u64, error) !=
		    DW_DLE_NONE)
			return (DW_DLV_ERROR);
	}
	if (cu->cu_lineinfo == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
		return (DW_DLV_NO_ENTRY);
	}

	li = cu->cu_lineinfo;
	*linecount = (Dwarf_Signed) li->li_lnlen;

	if (*linecount == 0) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
		return (DW_DLV_NO_ENTRY);
	}

	if (li->li_lnarray != NULL) {
		*linebuf = li->li_lnarray;
		return (DW_DLV_OK);
	}

	if ((li->li_lnarray = malloc(*linecount * sizeof(Dwarf_Line))) ==
	    NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
		return (DW_DLV_ERROR);
	}

	for (i = 0, ln = STAILQ_FIRST(&li->li_lnlist);
	     i < *linecount && ln != NULL; i++, ln = STAILQ_NEXT(ln, ln_next))
		li->li_lnarray[i] = ln;

	*linebuf = li->li_lnarray;

	return (DW_DLV_OK);
}
Exemple #12
0
int list_func_die(struct Ripdebuginfo *info, Dwarf_Die *die, uint64_t addr)
{
	_Dwarf_Line ln;
	Dwarf_Attribute *low;
	Dwarf_Attribute *high;
	Dwarf_CU *cu = die->cu_header;
	Dwarf_Die *cudie = die->cu_die; 
	Dwarf_Die ret, sib=*die; 
	Dwarf_Attribute *attr;
	uint64_t offset;
	uint64_t ret_val=8;
	
	if(die->die_tag != DW_TAG_subprogram)
		return 0;

	memset(&ln, 0, sizeof(_Dwarf_Line));

	low  = _dwarf_attr_find(die, DW_AT_low_pc);
	high = _dwarf_attr_find(die, DW_AT_high_pc);

	if((low && (low->u[0].u64 < addr)) && (high && (high->u[0].u64 > addr)))
	{
		info->rip_file = die->cu_die->die_name;

		info->rip_fn_name = die->die_name;
		info->rip_fn_namelen = strlen(die->die_name);

		info->rip_fn_addr = (uintptr_t)low->u[0].u64;

		assert(die->cu_die);	
		dwarf_srclines(die->cu_die, &ln, addr, NULL); 

		info->rip_line = ln.ln_lineno;
		info->rip_fn_narg = 0;

		Dwarf_Attribute* attr;

		if(dwarf_child(dbg, cu, &sib, &ret) != DW_DLE_NO_ENTRY)
		{
			if(ret.die_tag != DW_TAG_formal_parameter)
				goto last;

			attr = _dwarf_attr_find(&ret, DW_AT_type);
	
		try_again:
			if(attr != NULL)
			{
				offset = (uint64_t)cu->cu_offset + attr->u[0].u64;
				dwarf_offdie(dbg, offset, &sib, *cu);
				attr = _dwarf_attr_find(&sib, DW_AT_byte_size);
		
				if(attr != NULL)
				{
					ret_val = attr->u[0].u64;
				}
				else
				{
					attr = _dwarf_attr_find(&sib, DW_AT_type);
					goto try_again;
				}
			}
			info->size_fn_arg[info->rip_fn_narg] = ret_val;
			info->rip_fn_narg++;
			sib = ret; 

			while(dwarf_siblingof(dbg, &sib, &ret, cu) == DW_DLV_OK)	
			{
				if(ret.die_tag != DW_TAG_formal_parameter)
					break;

				attr = _dwarf_attr_find(&ret, DW_AT_type);
    
				if(attr != NULL)
				{	   
					offset = (uint64_t)cu->cu_offset + attr->u[0].u64;
					dwarf_offdie(dbg, offset, &sib, *cu);
					attr = _dwarf_attr_find(&sib, DW_AT_byte_size);
        
					if(attr != NULL)
					{
						ret_val = attr->u[0].u64;
					}
				}
	
				info->size_fn_arg[info->rip_fn_narg]=ret_val;// _get_arg_size(ret);
				info->rip_fn_narg++;
				sib = ret; 
			}
		}
	last:	
		return 1;
	}

	return 0;
}