Esempio n. 1
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);
}
int
dwarf_get_vars(Dwarf_Debug dbg, Dwarf_Var **vars,
    Dwarf_Signed *ret_count, Dwarf_Error *error)
{
	Dwarf_Section *ds;
	int ret;

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

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

	*vars = dbg->dbg_vars->ns_array;
	*ret_count = dbg->dbg_vars->ns_len;

	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);
}
Esempio n. 4
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);
}
Esempio n. 5
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);
}
Esempio n. 6
0
static int
_dwarf_consumer_init(Dwarf_Debug dbg, Dwarf_Error *error)
{
	const Dwarf_Obj_Access_Methods *m;
	Dwarf_Obj_Access_Section sec;
	void *obj;
	Dwarf_Unsigned cnt;
	Dwarf_Half i;
	int ret;

	assert(dbg != NULL);
	assert(dbg->dbg_iface != NULL);

	m = dbg->dbg_iface->methods;
	obj = dbg->dbg_iface->object;

	assert(m != NULL);
	assert(obj != NULL);

	if (m->get_byte_order(obj) == DW_OBJECT_MSB) {
		dbg->read = _dwarf_read_msb;
		dbg->write = _dwarf_write_msb;
		dbg->decode = _dwarf_decode_msb;
	} else {
		dbg->read = _dwarf_read_lsb;
		dbg->write = _dwarf_write_lsb;
		dbg->decode = _dwarf_decode_lsb;
	}

	dbg->dbg_pointer_size = m->get_pointer_size(obj);
	dbg->dbg_offset_size = m->get_length_size(obj);

	cnt = m->get_section_count(obj);

	if (cnt == 0) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_INFO_NULL);
		return (DW_DLE_DEBUG_INFO_NULL);
	}

	dbg->dbg_seccnt = cnt;

	if ((dbg->dbg_section = calloc(cnt, sizeof(Dwarf_Section))) == NULL) {
		DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
		return (DW_DLE_MEMORY);
	}

	for (i = 0; i < cnt; i++) {
		if (m->get_section_info(obj, i, &sec, &ret) != DW_DLV_OK) {
			free(dbg->dbg_section);
			DWARF_SET_ERROR(dbg, error, ret);
			return (ret);
		}

		dbg->dbg_section[i].ds_addr = sec.addr;
		dbg->dbg_section[i].ds_size = sec.size;
		dbg->dbg_section[i].ds_name = sec.name;

		if (m->load_section(obj, i, &dbg->dbg_section[i].ds_data, &ret)
		    != DW_DLV_OK) {
			free(dbg->dbg_section);
			DWARF_SET_ERROR(dbg, error, ret);
			return (ret);
		}
	}

	if (_dwarf_find_section(dbg, ".debug_abbrev") == NULL ||
	    ((dbg->dbg_info_sec = _dwarf_find_section(dbg, ".debug_info")) ==
	     NULL)) {
		free(dbg->dbg_section);
		DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_INFO_NULL);
		return (DW_DLE_DEBUG_INFO_NULL);
	}

	/* Initialise call frame API related parameters. */
	_dwarf_frame_params_init(dbg);

	return (DW_DLV_OK);
}
Esempio n. 7
0
// debuginfo_rip(addr, info)
//
//	Fill in the 'info' structure with information about the specified
//	instruction address, 'addr'.  Returns 0 if information was found, and
//	negative if not.  But even if it returns negative it has stored some
//	information into '*info'.
//
int
debuginfo_rip(uintptr_t addr, struct Ripdebuginfo *info)
{
	static struct Env* lastenv = NULL;
	void* elf;    
	Dwarf_Section *sect;
	Dwarf_CU cu;
	Dwarf_Die die, cudie, die2;
	Dwarf_Regtable *rt = NULL;
	//Set up initial pc
	uint64_t pc  = (uintptr_t)addr;

    
	// Initialize *info
	info->rip_file = "<unknown>";
	info->rip_line = 0;
	info->rip_fn_name = "<unknown>";
	info->rip_fn_namelen = 9;
	info->rip_fn_addr = addr;
	info->rip_fn_narg = 0;
    
	// Find the relevant set of stabs
	if (addr >= ULIM) {
		elf = (void *)0x10000 + KERNBASE;
	} else {
		// Can't search for user-level addresses yet!
		panic("User address");
	}
    
    
	_dwarf_init(dbg, elf);

	sect = _dwarf_find_section(".debug_info");	
	dbg->dbg_info_offset_elf = (uint64_t)sect->ds_data; 
	dbg->dbg_info_size = sect->ds_size;
    
	assert(dbg->dbg_info_size);
	while(_get_next_cu(dbg, &cu) == 0)
	{
		if(dwarf_siblingof(dbg, NULL, &cudie, &cu) == DW_DLE_NO_ENTRY)
		{
			continue;
		}	
		cudie.cu_header = &cu;
		cudie.cu_die = NULL;
	    
		if(dwarf_child(dbg, &cu, &cudie, &die) == DW_DLE_NO_ENTRY)
		{
			continue;
		}	
		die.cu_header = &cu;
		die.cu_die = &cudie;
		while(1)
		{
			if(list_func_die(info, &die, addr))
				goto find_done;
			if(dwarf_siblingof(dbg, &die, &die2, &cu) < 0)
				break; 
			die = die2;
			die.cu_header = &cu;
			die.cu_die = &cudie;
		}
	}
    
	return -1;

find_done:
	return 0;

}