Example #1
0
int
dwarf_linesrc(Dwarf_Line ln, char **ret_linesrc, Dwarf_Error *error)
{
	Dwarf_LineInfo li;
	Dwarf_LineFile lf;
	int i;

	if (ln == NULL || ret_linesrc == NULL) {
		DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	li = ln->ln_li;
	assert(li != NULL);

	for (i = 1, lf = STAILQ_FIRST(&li->li_lflist);
	     (Dwarf_Unsigned) i < ln->ln_fileno && lf != NULL;
	     i++, lf = STAILQ_NEXT(lf, lf_next))
		;

	if (lf == NULL) {
		DWARF_SET_ERROR(NULL, error, DW_DLE_LINE_FILE_NUM_BAD);
		return (DW_DLV_ERROR);
	}

	if (lf->lf_fullpath) {
		*ret_linesrc = (char *) lf->lf_fullpath;
		return (DW_DLV_OK);
	}

	*ret_linesrc = lf->lf_fname;

	return (DW_DLV_OK);
}
Example #2
0
int
dwarf_get_str(Dwarf_Debug dbg, Dwarf_Off offset, char **string,
    Dwarf_Signed *ret_strlen, Dwarf_Error *error)
{
	Dwarf_Section *ds;

	if (dbg == NULL || offset < 0 || string == NULL || ret_strlen == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	ds = _dwarf_find_section(dbg, ".debug_str");
	if (ds == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
		return (DW_DLV_NO_ENTRY);
	}

	if ((Dwarf_Unsigned) offset > ds->ds_size) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	if ((Dwarf_Unsigned) offset == ds->ds_size) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
		return (DW_DLV_NO_ENTRY);
	}

	*string = (char *) ds->ds_data + offset;
	*ret_strlen = strlen(*string);

	return (DW_DLV_OK);
}
Example #3
0
int
dwarf_attr_add(Dwarf_Abbrev a, uint64_t attr, uint64_t form, Dwarf_Attribute *atp, Dwarf_Error *error)
{
	Dwarf_Attribute at;
	int ret = DWARF_E_NONE;

	if (error == NULL)
		return DWARF_E_ERROR;

	if (a == NULL) {
		DWARF_SET_ERROR(error, DWARF_E_ARGUMENT);
		return DWARF_E_ARGUMENT;
	}

	if ((at = malloc(sizeof(struct _Dwarf_Attribute))) == NULL) {
		DWARF_SET_ERROR(error, DWARF_E_MEMORY);
		return DWARF_E_MEMORY;
	}

	/* Initialise the attribute structure. */
	at->at_attrib	= attr;
	at->at_form	= form;

	/* Add the attribute to the list in the abbrev. */
	STAILQ_INSERT_TAIL(&a->a_attrib, at, at_next);

	if (atp != NULL)
		*atp = at;

	return ret;
}
Example #4
0
int
dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev, Dwarf_Signed ndx,
    Dwarf_Half *attr_num, Dwarf_Signed *form, Dwarf_Off *offset,
    Dwarf_Error *error)
{
	Dwarf_AttrDef ad;
	int i;

	if (abbrev == NULL || attr_num == NULL || form == NULL ||
	    offset == NULL) {
		DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	if (ndx < 0 || (uint64_t) ndx >= abbrev->ab_atnum) {
		DWARF_SET_ERROR(NULL, error, DW_DLE_NO_ENTRY);
		return (DW_DLV_NO_ENTRY);
	}

	ad = STAILQ_FIRST(&abbrev->ab_attrdef);
	for (i = 0; i < ndx && ad != NULL; i++)
		ad = STAILQ_NEXT(ad, ad_next);

	assert(ad != NULL);

	*attr_num = ad->ad_attrib;
	*form = ad->ad_form;
	*offset = ad->ad_offset;

	return (DW_DLV_OK);
}
int
dwarf_get_pubtypes(Dwarf_Debug dbg, Dwarf_Type **pubtypes,
    Dwarf_Signed *ret_count, Dwarf_Error *error)
{
	Dwarf_Section *ds;
	int ret;

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

	if (dbg->dbg_pubtypes == NULL) {
		if ((ds = _dwarf_find_section(dbg, ".debug_pubtypes")) != NULL) {
			ret = _dwarf_nametbl_init(dbg, &dbg->dbg_pubtypes, ds,
			    error);
			if (ret != DW_DLE_NONE)
				return (DW_DLV_ERROR);
		}
		if (dbg->dbg_pubtypes == NULL) {
			DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
			return (DW_DLV_NO_ENTRY);
		}
	}

	*pubtypes = dbg->dbg_pubtypes->ns_array;
	*ret_count = dbg->dbg_pubtypes->ns_len;

	return (DW_DLV_OK);
}
Example #6
0
int
dwarf_attr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Attribute *atp, Dwarf_Error *err)
{
	Dwarf_Attribute at;
	Dwarf_Abbrev	a;
	int ret = DWARF_E_NONE;

	if (err == NULL)
		return DWARF_E_ERROR;

	if (die == NULL || atp == NULL || (a = die->die_a) == NULL) {
		DWARF_SET_ERROR(err, DWARF_E_ARGUMENT);
		return DWARF_E_ARGUMENT;
	}

	STAILQ_FOREACH(at, &a->a_attrib, at_next)
		if (at->at_attrib == attr)
			break;

	*atp = at;

	if (at == NULL) {
		DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY);
		ret = DWARF_E_NO_ENTRY;
	}

	return ret;
}
Example #7
0
int
_dwarf_loc_fill_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc *llbuf, uint8_t *in,
    uint64_t in_len, uint8_t pointer_size, uint8_t offset_size,
    uint8_t version, Dwarf_Error *error)
{
	int num;

	assert(llbuf != NULL);
	assert(in != NULL);
	assert(in_len > 0);

	/* Compute the number of locations. */
	if ((num = _dwarf_loc_fill_loc(dbg, NULL, pointer_size, offset_size,
	    version, in, in_len)) < 0) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_LOC_EXPR_BAD);
		return (DW_DLE_LOC_EXPR_BAD);
	}

	llbuf->ld_cents = num;
	if (num <= 0)
		return (DW_DLE_NONE);

	if ((llbuf->ld_s = calloc(num, sizeof(Dwarf_Loc))) == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
		return (DW_DLE_MEMORY);
	}

	(void) _dwarf_loc_fill_loc(dbg, llbuf, pointer_size, offset_size,
	    version, in, in_len);

	return (DW_DLE_NONE);
}
Example #8
0
int
dwarf_get_abbrev(Dwarf_Debug dbg, Dwarf_Unsigned offset,
    Dwarf_Abbrev *return_abbrev, Dwarf_Unsigned *length,
    Dwarf_Unsigned *attr_count, Dwarf_Error *error)
{
	Dwarf_Abbrev ab;
	int ret;

	if (dbg == NULL || return_abbrev == NULL || length == NULL ||
	    attr_count == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	ret = _dwarf_abbrev_parse(dbg, NULL, &offset, &ab, error);
	if (ret != DW_DLE_NONE) {
		if (ret == DW_DLE_NO_ENTRY) {
			DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
			return (DW_DLV_NO_ENTRY);
		} else
			return (DW_DLV_ERROR);
	}

	*return_abbrev = ab;
	*length = ab->ab_length;
	*attr_count = ab->ab_atnum;

	return (DW_DLV_OK);
}
Example #9
0
Dwarf_P_Die
dwarf_die_link(Dwarf_P_Die die, Dwarf_P_Die parent,
    Dwarf_P_Die child, Dwarf_P_Die left_sibling, Dwarf_P_Die right_sibling,
    Dwarf_Error *error)
{
	Dwarf_Debug dbg;
	int count;


	if (die == NULL) {
		DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
		return (DW_DLV_BADADDR);
	}

	dbg = die->die_dbg;
	count = _dwarf_die_count_links(parent, child, left_sibling,
	    right_sibling);

	if (count > 1) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_BADADDR);
	} else if (count == 0)
		return (die);

	_dwarf_die_link(die, parent, child, left_sibling, right_sibling);

	return (die);
}
Example #10
0
int
dwarf_loclist_from_expr_b(Dwarf_Debug dbg, Dwarf_Ptr bytes_in,
    Dwarf_Unsigned bytes_len, Dwarf_Half addr_size, Dwarf_Half offset_size,
    Dwarf_Small version, Dwarf_Locdesc **llbuf, Dwarf_Signed *listlen,
    Dwarf_Error *error)
{
	Dwarf_Locdesc *ld;
	int ret;

	if (dbg == NULL || bytes_in == NULL || bytes_len == 0 ||
	    llbuf == NULL || listlen == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	if (addr_size != 4 && addr_size != 8) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	if (offset_size != 4 && offset_size != 8) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	ret = _dwarf_loc_fill_locexpr(dbg, &ld, bytes_in, bytes_len, addr_size,
	    offset_size, version, error);
	if (ret != DW_DLE_NONE)
		return (DW_DLV_ERROR);

	*llbuf = ld;
	*listlen = 1;

	return (DW_DLV_OK);
}
Dwarf_Unsigned
dwarf_add_arange_b(Dwarf_P_Debug dbg, Dwarf_Addr start, Dwarf_Unsigned length,
    Dwarf_Unsigned symbol_index, Dwarf_Unsigned end_symbol_index,
    Dwarf_Addr offset_from_end_symbol, Dwarf_Error *error)
{
	Dwarf_ArangeSet as;
	Dwarf_Arange ar;

	if (dbg == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (0);
	}
	as = dbg->dbgp_as;

	if (end_symbol_index > 0 &&
	    (dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (0);
	}

	if ((ar = calloc(1, sizeof(struct _Dwarf_Arange))) == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
		return (0);
	}
	ar->ar_as = as;
	ar->ar_address = start;
	ar->ar_range = length;
	ar->ar_symndx = symbol_index;
	ar->ar_esymndx = end_symbol_index;
	ar->ar_eoff = offset_from_end_symbol;
	STAILQ_INSERT_TAIL(&as->as_arlist, ar, ar_next);

	return (1);
}
Example #12
0
int
dwarf_next_cu_header_b(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length,
    Dwarf_Half *cu_version, Dwarf_Off *cu_abbrev_offset,
    Dwarf_Half *cu_pointer_size, Dwarf_Half *cu_offset_size,
    Dwarf_Half *cu_extension_size, Dwarf_Unsigned *cu_next_offset,
    Dwarf_Error *error)
{
	Dwarf_CU cu;
	int ret;

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

	if (dbg->dbg_cu_current == NULL)
		ret = _dwarf_info_first_cu(dbg, error);
	else
		ret = _dwarf_info_next_cu(dbg, error);

	if (ret == DW_DLE_NO_ENTRY) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
		return (DW_DLV_NO_ENTRY);
	} else if (ret != DW_DLE_NONE)
		return (DW_DLV_ERROR);

	if (dbg->dbg_cu_current == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
		return (DW_DLV_NO_ENTRY);
	}
	cu = dbg->dbg_cu_current;

	if (cu_length)
		*cu_length = cu->cu_length;
	if (cu_version)
		*cu_version = cu->cu_version;
	if (cu_abbrev_offset)
		*cu_abbrev_offset = (Dwarf_Off) cu->cu_abbrev_offset;
	if (cu_pointer_size)
		*cu_pointer_size = cu->cu_pointer_size;
	if (cu_offset_size) {
		if (cu->cu_length_size == 4)
			*cu_offset_size = 4;
		else
			*cu_offset_size = 8;
	}
	if (cu_extension_size) {
		if (cu->cu_length_size == 4)
			*cu_extension_size = 0;
		else
			*cu_extension_size = 4;
	}
	if (cu_next_offset)
		*cu_next_offset	= dbg->dbg_cu_current->cu_next_offset;

	return (DW_DLV_OK);
}
int
dwarf_get_loclist_entry(Dwarf_Debug dbg, Dwarf_Unsigned offset,
    Dwarf_Addr *hipc, Dwarf_Addr *lopc, Dwarf_Ptr *data,
    Dwarf_Unsigned *entry_len, Dwarf_Unsigned *next_entry,
    Dwarf_Error *error)
{
	Dwarf_Loclist ll, next_ll;
	Dwarf_Locdesc *ld;
	Dwarf_Section *ds;
	int i, ret;

	if (dbg == NULL || hipc == NULL || lopc == NULL || data == NULL ||
	    entry_len == NULL || next_entry == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	ret = _dwarf_loclist_find(dbg, STAILQ_FIRST(&dbg->dbg_cu), offset, &ll,
	    error);
	if (ret == DW_DLE_NO_ENTRY) {
		DWARF_SET_ERROR(dbg, error, DW_DLV_NO_ENTRY);
		return (DW_DLV_NO_ENTRY);
	} else if (ret != DW_DLE_NONE)
		return (DW_DLV_ERROR);

	*hipc = *lopc = 0;
	for (i = 0; i < ll->ll_ldlen; i++) {
		ld = ll->ll_ldlist[i];
		if (i == 0) {
			*hipc = ld->ld_hipc;
			*lopc = ld->ld_lopc;
		} else {
			if (ld->ld_lopc < *lopc)
				*lopc = ld->ld_lopc;
			if (ld->ld_hipc > *hipc)
				*hipc = ld->ld_hipc;
		}
	}

	ds = _dwarf_find_section(dbg, ".debug_loc");
	assert(ds != NULL);
	*data = (uint8_t *) ds->ds_data + ll->ll_offset;
	*entry_len = ll->ll_length;

	next_ll = TAILQ_NEXT(ll, ll_next);
	if (next_ll != NULL)
		*next_entry = next_ll->ll_offset;
	else
		*next_entry = ds->ds_size;

	return (DW_DLV_OK);
}
Example #14
0
int
dwarf_get_loclist_entry(Dwarf_Debug dbg, Dwarf_Unsigned offset,
    Dwarf_Addr *hipc, Dwarf_Addr *lopc, Dwarf_Ptr *data,
    Dwarf_Unsigned *entry_len, Dwarf_Unsigned *next_entry,
    Dwarf_Error *error)
{
	Dwarf_Locdesc *ld, **llbuf;
	Dwarf_Section *ds;
	Dwarf_Signed listlen;
	int i, ret;

	/*
	 * Note that this API sometimes will not work correctly because
	 * it assumes that all units have the same pointer size and offset
	 * size.
	 */

	if (dbg == NULL || hipc == NULL || lopc == NULL || data == NULL ||
	    entry_len == NULL || next_entry == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	ret = _dwarf_loclist_find(dbg, STAILQ_FIRST(&dbg->dbg_cu), offset,
	    &llbuf, &listlen, entry_len, error);
	if (ret == DW_DLE_NO_ENTRY) {
		DWARF_SET_ERROR(dbg, error, DW_DLV_NO_ENTRY);
		return (DW_DLV_NO_ENTRY);
	} else if (ret != DW_DLE_NONE)
		return (DW_DLV_ERROR);

	*hipc = *lopc = 0;
	for (i = 0; i < listlen; i++) {
		ld = llbuf[i];
		if (i == 0) {
			*hipc = ld->ld_hipc;
			*lopc = ld->ld_lopc;
		} else {
			if (ld->ld_lopc < *lopc)
				*lopc = ld->ld_lopc;
			if (ld->ld_hipc > *hipc)
				*hipc = ld->ld_hipc;
		}
	}

	ds = _dwarf_find_section(dbg, ".debug_loc");
	assert(ds != NULL);
	*data = (uint8_t *) ds->ds_data + offset;
	*next_entry = offset + *entry_len;

	return (DW_DLV_OK);
}
Example #15
0
int
dwarf_get_fde_info_for_reg(Dwarf_Fde fde, Dwarf_Half table_column,
    Dwarf_Addr pc_requested, Dwarf_Signed *offset_relevant,
    Dwarf_Signed *register_num, Dwarf_Signed *offset, Dwarf_Addr *row_pc,
    Dwarf_Error *error)
{
	Dwarf_Regtable3 *rt;
	Dwarf_Debug dbg;
	Dwarf_Addr pc;
	int ret;

	dbg = fde != NULL ? fde->fde_dbg : NULL;

	if (fde == NULL || offset_relevant == NULL || register_num == NULL ||
	    offset == NULL || row_pc == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	if (pc_requested < fde->fde_initloc ||
	    pc_requested >= fde->fde_initloc + fde->fde_adrange) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE);
		return (DW_DLV_ERROR);
	}

	ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc,
	    error);
	if (ret != DW_DLE_NONE)
		return (DW_DLV_ERROR);

	if (table_column == dbg->dbg_frame_cfa_value) {
		/* Application ask for CFA. */
		*offset_relevant = CFA.dw_offset_relevant;
		*register_num = CFA.dw_regnum;
		*offset = CFA.dw_offset_or_block_len;
	} else {
		/* Application ask for normal registers. */
		if (table_column >= dbg->dbg_frame_rule_table_size ||
		    table_column >= DW_REG_TABLE_SIZE) {
			DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD);
			return (DW_DLV_ERROR);
		}

		*offset_relevant = RL.dw_offset_relevant;
		*register_num = RL.dw_regnum;
		*offset = RL.dw_offset_or_block_len;
	}

	*row_pc = pc;

	return (DW_DLV_OK);
}
Example #16
0
int
dwarf_init(int fd, int mode, Dwarf_Handler errhand, Dwarf_Ptr errarg,
    Dwarf_Debug *ret_dbg, Dwarf_Error *error)
{
	Dwarf_Debug dbg;
	Elf *elf;
	int ret;

	if (fd < 0 || ret_dbg == NULL) {
		DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	if (mode != DW_DLC_READ) {
		DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	if (elf_version(EV_CURRENT) == EV_NONE) {
		DWARF_SET_ELF_ERROR(NULL, error);
		return (DW_DLV_ERROR);
	}

	if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
		DWARF_SET_ELF_ERROR(NULL, error);
		return (DW_DLV_ERROR);
	}

	if (_dwarf_alloc(&dbg, mode, error) != DW_DLE_NONE)
		return (DW_DLV_ERROR);

	if (_dwarf_elf_init(dbg, elf, error) != DW_DLE_NONE) {
		free(dbg);
		return (DW_DLV_ERROR);
	}

	if ((ret = _dwarf_init(dbg, 0, errhand, errarg, error)) !=
	    DW_DLE_NONE) {
		_dwarf_elf_deinit(dbg);
		free(dbg);
		if (ret == DW_DLE_DEBUG_INFO_NULL)
			return (DW_DLV_NO_ENTRY);
		else
			return (DW_DLV_ERROR);
	}

	*ret_dbg = dbg;

	return (DW_DLV_OK);
}
Example #17
0
Dwarf_Unsigned
dwarf_add_frame_fde_b(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die,
    Dwarf_Unsigned cie, Dwarf_Addr virt_addr, Dwarf_Unsigned code_len,
    Dwarf_Unsigned symbol_index, Dwarf_Unsigned end_symbol_index,
    Dwarf_Addr offset_from_end_sym, Dwarf_Error *error)
{
	Dwarf_P_Cie ciep;
	int i;

	/*
	 * XXX SGI libdwarf need the DIE arg because later it will insert a
	 * DW_AT_MIPS_fde attribute, which points to the offset the
	 * correspoding FDE, into this DIE. Do we need this?
	 */
	(void) die;

	if (dbg == NULL || fde == NULL || fde->fde_dbg != dbg) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_NOCOUNT);
	}

	ciep = STAILQ_FIRST(&dbg->dbgp_cielist);
	for (i = 0; (Dwarf_Unsigned) i < cie; i++) {
		ciep = STAILQ_NEXT(ciep, cie_next);
		if (ciep == NULL)
			break;
	}
	if (ciep == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_NOCOUNT);
	}

	if (end_symbol_index > 0 &&
	    (dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_NOCOUNT);
	}

	fde->fde_cie = ciep;
	fde->fde_initloc = virt_addr;
	fde->fde_adrange = code_len;
	fde->fde_symndx = symbol_index;
	fde->fde_esymndx = end_symbol_index;
	fde->fde_eoff = offset_from_end_sym;

	STAILQ_INSERT_TAIL(&dbg->dbgp_fdelist, fde, fde_next);

	return (dbg->dbgp_fdelen++);
}
int
_dwarf_loc_fill_locexpr(Dwarf_Debug dbg, Dwarf_Locdesc **ret_llbuf, uint8_t *in,
    uint64_t in_len, uint8_t pointer_size, Dwarf_Error *error)
{
	Dwarf_Locdesc *llbuf;
	int ret;

	if ((llbuf = malloc(sizeof(Dwarf_Locdesc))) == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
		return (DW_DLE_MEMORY);
	}
	llbuf->ld_lopc = 0;
	llbuf->ld_hipc = ~0ULL;
	llbuf->ld_s = NULL;

	ret = _dwarf_loc_fill_locdesc(dbg, llbuf, in, in_len, pointer_size,
	    error);
	if (ret != DW_DLE_NONE) {
		free(llbuf);
		return (ret);
	}

	*ret_llbuf = llbuf;

	return (ret);
}
int
dwarf_var_name_offsets(Dwarf_Var var, char **ret_name, Dwarf_Off *die_offset,
    Dwarf_Off *cu_offset, Dwarf_Error *error)
{
	Dwarf_CU cu;
	Dwarf_Debug dbg;
	Dwarf_NameTbl nt;

	dbg = var != NULL ? var->np_nt->nt_cu->cu_dbg : NULL;

	if (var == NULL || ret_name == NULL || die_offset == NULL ||
	    cu_offset == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	nt = var->np_nt;
	assert(nt != NULL);

	cu = nt->nt_cu;
	assert(cu != NULL);

	*ret_name = var->np_name;
	*die_offset = nt->nt_cu_offset + var->np_offset;
	*cu_offset = cu->cu_1st_offset;

	return (DW_DLV_OK);
}
Example #20
0
int
dwarf_object_init(Dwarf_Obj_Access_Interface *iface, Dwarf_Handler errhand,
    Dwarf_Ptr errarg, Dwarf_Debug *ret_dbg, Dwarf_Error *error)
{
	Dwarf_Debug dbg;

	if (iface == NULL || ret_dbg == NULL) {
		DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	if (_dwarf_alloc(&dbg, DW_DLC_READ, error) != DW_DLE_NONE)
		return (DW_DLV_ERROR);

	dbg->dbg_iface = iface;

	if (_dwarf_init(dbg, 0, errhand, errarg, error) != DW_DLE_NONE) {
		free(dbg);
		return (DW_DLV_ERROR);
	}

	*ret_dbg = dbg;

	return (DW_DLV_OK);
}
Example #21
0
int
dwarf_get_cie_info(Dwarf_Cie cie, Dwarf_Unsigned *bytes_in_cie,
    Dwarf_Small *version, char **augmenter, Dwarf_Unsigned *caf,
    Dwarf_Unsigned *daf, Dwarf_Half *ra, Dwarf_Ptr *initinst,
    Dwarf_Unsigned *inst_len, Dwarf_Error *error)
{

	if (cie == NULL || bytes_in_cie == NULL || version == NULL ||
	    augmenter == NULL || caf == NULL || daf == NULL || ra == NULL ||
	    initinst == NULL || inst_len == NULL) {
		DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	*bytes_in_cie = cie->cie_length;
	*version = cie->cie_version;
	*augmenter = (char *) cie->cie_augment;
	*caf = cie->cie_caf;
	*daf = cie->cie_daf;
	*ra = cie->cie_ra;
	*initinst = cie->cie_initinst;
	*inst_len = cie->cie_instlen;

	return (DW_DLV_OK);
}
Example #22
0
int
dwarf_get_fde_range(Dwarf_Fde fde, Dwarf_Addr *low_pc, Dwarf_Unsigned *func_len,
    Dwarf_Ptr *fde_bytes, Dwarf_Unsigned *fde_byte_len, Dwarf_Off *cie_offset,
    Dwarf_Signed *cie_index, Dwarf_Off *fde_offset, Dwarf_Error *error)
{
	Dwarf_Debug dbg;

	dbg = fde != NULL ? fde->fde_dbg : NULL;

	if (fde == NULL || low_pc == NULL || func_len == NULL ||
	    fde_bytes == NULL || fde_byte_len == NULL || cie_offset == NULL ||
	    cie_index == NULL || fde_offset == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	*low_pc = fde->fde_initloc;
	*func_len = fde->fde_adrange;
	*fde_bytes = fde->fde_addr;
	*fde_byte_len = fde->fde_length;
	*cie_offset = fde->fde_cieoff;
	*cie_index = fde->fde_cie->cie_index;
	*fde_offset = fde->fde_offset;

	return (DW_DLV_OK);
}
Example #23
0
int
_dwarf_strtab_gen(Dwarf_P_Debug dbg, Dwarf_Error *error)
{
	Dwarf_P_Section ds;
	int ret;

	assert(dbg != NULL);

	if ((ret = _dwarf_section_init(dbg, &ds, ".debug_str", 0, error)) !=
	    DW_DLE_NONE)
		return (ret);

	if (dbg->dbg_strtab_size > ds->ds_cap) {
		ds->ds_data = realloc(ds->ds_data,
		    (size_t) dbg->dbg_strtab_size);
		if (ds->ds_data == NULL) {
			_dwarf_section_free(dbg, &ds);
			DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
			return (DW_DLE_MEMORY);
		}
		ds->ds_cap = dbg->dbg_strtab_size;
	}

	memcpy(ds->ds_data, dbg->dbg_strtab, dbg->dbg_strtab_size);
	ds->ds_size = dbg->dbg_strtab_size;

	/*
	 * Inform application the creation of .debug_str ELF section.
	 * Note that .debug_str use a different format than usual ELF
	 * string table, so it should not have SHT_STRTAB as its type.
	 */
	ret = _dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error);

	return (ret);
}
Example #24
0
int
_dwarf_strtab_add(Dwarf_Debug dbg, char *string, uint64_t *off,
    Dwarf_Error *error)
{
	size_t len;

	assert(dbg != NULL && string != NULL);

	len = strlen(string) + 1;
	while (dbg->dbg_strtab_size + len > dbg->dbg_strtab_cap) {
		dbg->dbg_strtab_cap *= 2;
		dbg->dbg_strtab = realloc(dbg->dbg_strtab,
		    (size_t) dbg->dbg_strtab_cap);
		if (dbg->dbg_strtab == NULL) {
			DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
			return (DW_DLE_MEMORY);
		}
	}

	if (off != NULL)
		*off = dbg->dbg_strtab_size;

	strncpy(&dbg->dbg_strtab[dbg->dbg_strtab_size], string, len - 1);
	dbg->dbg_strtab_size += len;
	dbg->dbg_strtab[dbg->dbg_strtab_size - 1] = '\0';

	return (DW_DLE_NONE);
}
int
dwarf_pubtype_name_offsets(Dwarf_Type pubtype, char **ret_name, Dwarf_Off *die_offset,
    Dwarf_Off *cu_offset, Dwarf_Error *error)
{
	Dwarf_CU cu;
	Dwarf_Debug dbg;
	Dwarf_NameTbl nt;

	dbg = pubtype != NULL ? pubtype->np_nt->nt_cu->cu_dbg : NULL;

	if (pubtype == NULL || ret_name == NULL || die_offset == NULL ||
	    cu_offset == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	nt = pubtype->np_nt;
	assert(nt != NULL);

	cu = nt->nt_cu;
	assert(cu != NULL);

	*ret_name = pubtype->np_name;
	*die_offset = nt->nt_cu_offset + pubtype->np_offset;
	*cu_offset = cu->cu_1st_offset;

	return (DW_DLV_OK);
}
Example #26
0
int
dwarf_get_fde_info_for_reg3(Dwarf_Fde fde, Dwarf_Half table_column,
    Dwarf_Addr pc_requested, Dwarf_Small *value_type,
    Dwarf_Signed *offset_relevant, Dwarf_Signed *register_num,
    Dwarf_Signed *offset_or_block_len, Dwarf_Ptr *block_ptr,
    Dwarf_Addr *row_pc, Dwarf_Error *error)
{
	Dwarf_Regtable3 *rt;
	Dwarf_Debug dbg;
	Dwarf_Addr pc;
	int ret;

	dbg = fde != NULL ? fde->fde_dbg : NULL;

	if (fde == NULL || value_type == NULL || offset_relevant == NULL ||
	    register_num == NULL || offset_or_block_len == NULL ||
	    block_ptr == NULL || row_pc == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_ERROR);
	}

	if (pc_requested < fde->fde_initloc ||
	    pc_requested >= fde->fde_initloc + fde->fde_adrange) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE);
		return (DW_DLV_ERROR);
	}

	ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc,
	    error);
	if (ret != DW_DLE_NONE)
		return (DW_DLV_ERROR);

	if (table_column >= dbg->dbg_frame_rule_table_size) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD);
		return (DW_DLV_ERROR);
	}

	*value_type = RL.dw_value_type;
	*offset_relevant = RL.dw_offset_relevant;
	*register_num = RL.dw_regnum;
	*offset_or_block_len = RL.dw_offset_or_block_len;
	*block_ptr = RL.dw_block_ptr;
	*row_pc = pc;

	return (DW_DLV_OK);
}
Example #27
0
int
dwarf_die_add(Dwarf_CU cu, int level, uint64_t offset, uint64_t abnum, Dwarf_Abbrev a, Dwarf_Die *diep, Dwarf_Error *err)
{
	Dwarf_Die die;
	uint64_t key;
	int ret = DWARF_E_NONE;

	if (err == NULL)
		return DWARF_E_ERROR;

	if (cu == NULL || a == NULL) {
		DWARF_SET_ERROR(err, DWARF_E_ARGUMENT);
		return DWARF_E_ARGUMENT;
	}

	if ((die = malloc(sizeof(struct _Dwarf_Die))) == NULL) {
		DWARF_SET_ERROR(err, DWARF_E_MEMORY);
		return DWARF_E_MEMORY;
	}

	/* Initialise the abbrev structure. */
	die->die_level	= level;
	die->die_offset	= offset;
	die->die_abnum	= abnum;
	die->die_a	= a;
	die->die_cu	= cu;
	die->die_name	= anon_name;

	/* Initialise the list of attribute values. */
	STAILQ_INIT(&die->die_attrval);

	/* Add the die to the list in the compilation unit. */
	STAILQ_INSERT_TAIL(&cu->cu_die, die, die_next);

	/* Add the die to the hash table in the compilation unit. */
	key = offset % DWARF_DIE_HASH_SIZE;
	STAILQ_INSERT_TAIL(&cu->cu_die_hash[key], die, die_hash);

	if (diep != NULL)
		*diep = die;

	return ret;
}
Dwarf_Unsigned
dwarf_add_frame_cie(Dwarf_P_Debug dbg, char *augmenter, Dwarf_Small caf,
    Dwarf_Small daf, Dwarf_Small ra, Dwarf_Ptr initinst,
    Dwarf_Unsigned inst_len, Dwarf_Error *error)
{
	Dwarf_P_Cie cie;

	if (dbg == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_NOCOUNT);
	}

	if ((cie = calloc(1, sizeof(struct _Dwarf_Cie))) == NULL) {
		DWARF_SET_ERROR(dbg, error,DW_DLE_MEMORY);
		return (DW_DLV_NOCOUNT);
	}
	STAILQ_INSERT_TAIL(&dbg->dbgp_cielist, cie, cie_next);

	cie->cie_index = dbg->dbgp_cielen++;

	if (augmenter != NULL) {
		cie->cie_augment = (uint8_t *) strdup(augmenter);
		if (cie->cie_augment == NULL) {
			DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
			return (DW_DLV_NOCOUNT);
		}
	}

	cie->cie_caf = caf;
	cie->cie_daf = (int8_t) daf; /* daf is signed. */
	cie->cie_ra = ra;
	if (initinst != NULL && inst_len > 0) {
		cie->cie_initinst = malloc((size_t) inst_len);
		if (cie->cie_initinst == NULL) {
			DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
			return (DW_DLV_NOCOUNT);
		}
		memcpy(cie->cie_initinst, initinst, inst_len);
		cie->cie_instlen = inst_len;
	}

	return (cie->cie_index);
}
Dwarf_P_Fde
dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error *error)
{
	Dwarf_P_Fde fde;

	if (dbg == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
		return (DW_DLV_BADADDR);
	}

	if ((fde = calloc(1, sizeof(struct _Dwarf_Fde))) == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
		return (DW_DLV_BADADDR);
	}

	fde->fde_dbg = dbg;

	return (fde);
}
Example #30
0
int
_dwarf_strtab_init(Dwarf_Debug dbg, Dwarf_Error *error)
{
	Dwarf_Section *ds;

	assert(dbg != NULL);

	if (dbg->dbg_mode == DW_DLC_READ || dbg->dbg_mode == DW_DLC_RDWR) {
		ds = _dwarf_find_section(dbg, ".debug_str");
		if (ds == NULL) {
			dbg->dbg_strtab = NULL;
			dbg->dbg_strtab_cap = dbg->dbg_strtab_size = 0;
			return (DW_DLE_NONE);
		}

		dbg->dbg_strtab_cap = dbg->dbg_strtab_size = ds->ds_size;

		if (dbg->dbg_mode == DW_DLC_RDWR) {
			if ((dbg->dbg_strtab = malloc((size_t) ds->ds_size)) ==
			    NULL) {
				DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
				return (DW_DLE_MEMORY);
			}
			memcpy(dbg->dbg_strtab, ds->ds_data, ds->ds_size);
		} else
			dbg->dbg_strtab = (char *) ds->ds_data;
	} else {
		/* DW_DLC_WRITE */

		dbg->dbg_strtab_cap = _INIT_DWARF_STRTAB_SIZE;
		dbg->dbg_strtab_size = 0;

		if ((dbg->dbg_strtab = malloc((size_t) dbg->dbg_strtab_cap)) ==
		    NULL) {
			DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
			return (DW_DLE_MEMORY);
		}

		dbg->dbg_strtab[0] = '\0';
	}

	return (DW_DLE_NONE);
}