Ejemplo n.º 1
0
static void DC_resolve_type(Dwarf_Die v, DC_type *t){
 
  /*TODO: Error Handling*/ 
  Dwarf_Error error;
  Dwarf_Attribute type;
  Dwarf_Off off;
  Dwarf_Die typeDie;
  Dwarf_Half tag = 0; 
  
 /*
 * Start with the variable,  not its type.  The loop
 * unwraps all the types.
 */
  dwarf_attr(v, DW_AT_type, &type, &error);
  dwarf_formref(type, &off, &error);
  DC_get_die_from_CU_relative_offset(v, off, &typeDie);

  int points = 0;
  int arrs = 0;
  while( 1 ){

    Dwarf_Bool has;
    dwarf_hasattr(typeDie,DW_AT_type,&has,&error);
    if(!has){ 

      /*We've reached a base or structure type*/
      dwarf_diename(typeDie,&(t->name),&error);
  
      Dwarf_Attribute bsize;
      dwarf_attr(typeDie,DW_AT_byte_size,&bsize,&error);
      dwarf_formudata(bsize,(Dwarf_Unsigned*)(&t->byteSize),&error);
      t->indirectionLevel = points;
      t->arrayLevel = arrs;
      return;
      /*Note: I am assuming this must happen eventually.  can there
 *            be mutually referencing types?*/

    }

    /*Otherwise: this type has a type, so it is a pointer or a typedef
 *               or an array type.  For now, we're only going to correctly
 *               handle pointer types.(TODO:)
 */
    dwarf_tag(typeDie,&tag,&error);
    if(tag == DW_TAG_pointer_type){
      points++;
    }
    if(tag == DW_TAG_array_type){
      arrs++;
    }
    
    dwarf_attr(typeDie, DW_AT_type, &type, &error);
    dwarf_formref(type, &off, &error);

    /*Note, the next line uses v, because it can use anything in the CU*/
    DC_get_die_from_CU_relative_offset(v, off, &typeDie);

  }

}
Ejemplo n.º 2
0
char *get_type_str(Dwarf_Die *die)
{
	static char buf[256] = "";
	char *ptr = NULL;
	Dwarf_Die tdie;
	Dwarf_Attribute attr;

	if (!dwarf_attr(die, DW_AT_type, &attr))
		return "void";

	dwarf_formref_die(&attr, &tdie);

	if (dwarf_tag(&tdie) == DW_TAG_array_type)
		ptr = "[]";
	else if (dwarf_tag(&tdie) == DW_TAG_pointer_type)
		ptr = "*";
	else
		goto end_ok;

	dwarf_attr(&tdie, DW_AT_type, &attr);
	dwarf_formref_die(&attr, &tdie);

end_ok:
	sprintf(buf, "%s%s", dwarf_diename(&tdie), (ptr) ? ptr : "");

	return buf;
}
Ejemplo n.º 3
0
/* BASE must be a base type DIE referenced by a typed DWARF expression op.  */
static void
print_base_type (Dwarf_Die *base)
{
  assert (dwarf_tag (base) == DW_TAG_base_type);

  Dwarf_Attribute encoding;
  Dwarf_Word enctype;
  if (dwarf_attr (base, DW_AT_encoding, &encoding) == NULL
      || dwarf_formudata (&encoding, &enctype) != 0)
    error (EXIT_FAILURE, 0, "base type without encoding");

  Dwarf_Attribute bsize;
  Dwarf_Word bits;
  if (dwarf_attr (base, DW_AT_byte_size, &bsize) != NULL
      && dwarf_formudata (&bsize, &bits) == 0)
    bits *= 8;
  else if (dwarf_attr (base, DW_AT_bit_size, &bsize) == NULL
	   || dwarf_formudata (&bsize, &bits) != 0)
    error (EXIT_FAILURE, 0, "base type without byte or bit size");

  printf ("{%s,%s,%" PRIu64 "@[%" PRIx64 "]}",
	  dwarf_diename (base),
	  dwarf_encoding_string (enctype),
	  bits,
	  dwarf_dieoffset (base));
}
Ejemplo n.º 4
0
int
_dwarf_internal_get_die_comp_dir(Dwarf_Die die, const char **compdir_out,
    const char **compname_out,
    Dwarf_Error *error)
{
    Dwarf_Attribute comp_dir_attr = 0;
    Dwarf_Attribute comp_name_attr = 0;
    int resattr = 0;
    Dwarf_Debug dbg = 0;

    dbg = die->di_cu_context->cc_dbg;
    resattr = dwarf_attr(die, DW_AT_name, &comp_name_attr, error);
    if (resattr == DW_DLV_ERROR) {
        return resattr;
    }
    if (resattr == DW_DLV_OK) {
        int cres = DW_DLV_ERROR;
        char *name = 0;

        cres = dwarf_formstring(comp_name_attr, &name, error);
        if (cres == DW_DLV_ERROR) {
            dwarf_dealloc(dbg, comp_name_attr, DW_DLA_ATTR);
            return cres;
        } else if (cres == DW_DLV_OK) {
            *compname_out = (const char *)name;
        } else {
            /* FALL thru */
        }
    }
    if (resattr == DW_DLV_OK) {
        dwarf_dealloc(dbg, comp_name_attr, DW_DLA_ATTR);
    }
    resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error);
    if (resattr == DW_DLV_ERROR) {
        return resattr;
    }
    if (resattr == DW_DLV_OK) {
        int cres = DW_DLV_ERROR;
        char *cdir = 0;

        cres = dwarf_formstring(comp_dir_attr, &cdir, error);
        if (cres == DW_DLV_ERROR) {
            dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
            return cres;
        } else if (cres == DW_DLV_OK) {
            *compdir_out = (const char *) cdir;
        } else {
            /* FALL thru */
        }
    }
    if (resattr == DW_DLV_OK) {
        dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
    }
    return resattr;
}
Ejemplo n.º 5
0
/**
 * die_get_data_member_location - Get the data-member offset
 * @mb_die: a DIE of a member of a data structure
 * @offs: The offset of the member in the data structure
 *
 * Get the offset of @mb_die in the data structure including @mb_die, and
 * stores result offset to @offs. If any error occurs this returns errno.
 */
int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs)
{
	Dwarf_Attribute attr;
	Dwarf_Op *expr;
	size_t nexpr;
	int ret;

	if (dwarf_attr(mb_die, DW_AT_data_member_location, &attr) == NULL)
		return -ENOENT;

	if (dwarf_formudata(&attr, offs) != 0) {
		/* DW_AT_data_member_location should be DW_OP_plus_uconst */
		ret = dwarf_getlocation(&attr, &expr, &nexpr);
		if (ret < 0 || nexpr == 0)
			return -ENOENT;

		if (expr[0].atom != DW_OP_plus_uconst || nexpr != 1) {
			pr_debug("Unable to get offset:Unexpected OP %x (%zd)\n",
				 expr[0].atom, nexpr);
			return -ENOTSUP;
		}
		*offs = (Dwarf_Word)expr[0].number;
	}
	return 0;
}
Ejemplo n.º 6
0
/**
 * cu_get_comp_dir - Get the path of compilation directory
 * @cu_die: a CU DIE
 *
 * Get the path of compilation directory of given @cu_die.
 * Since this depends on DW_AT_comp_dir, older gcc will not
 * embedded it. In that case, this returns NULL.
 */
const char *cu_get_comp_dir(Dwarf_Die *cu_die)
{
	Dwarf_Attribute attr;
	if (dwarf_attr(cu_die, DW_AT_comp_dir, &attr) == NULL)
		return NULL;
	return dwarf_formstring(&attr);
}
Ejemplo n.º 7
0
Dwarf_Attribute DieHolder::get_attr(int attr)
{
  Dwarf_Attribute attrib = NULL;
  MapAttrs::const_iterator iter = m_attrs.find(attr);

  if(iter == m_attrs.end())
  {
    Dwarf_Error err = NULL;

    // atribute may be NULL
    CHECK_DWERR2(dwarf_attr(m_die, attr, &attrib, &err) == DW_DLV_ERROR, err,
                 "cannot get DIE attribute %d", attr);

    if(attrib != NULL)
    {
      m_attrs[attr] = attrib;
    }
    else if(m_origin_holder.get() != NULL)
    {
      attrib = m_origin_holder->get_attr(attr);
    }
  }
  else
  {
    attrib = iter->second;
  }

  return attrib;
}
Ejemplo n.º 8
0
bool supported_language(Dwarf_Die *cu)
{
    int ret;
    Dwarf_Word lang;
    Dwarf_Attribute at;

    if (dwarf_attr(cu, DW_AT_language, &at) == NULL)
    {
        warn("CU %s: unknown language", dwarf_diename(cu));
        return false;
    }

    ret = dwarf_formudata(&at, &lang);
    fail_if(ret == -1, "dwarf_formudata");

    switch (lang)
    {
    case DW_LANG_C89:
    case DW_LANG_C:
    case DW_LANG_C99:
        /* good! */
        break;
    case DW_LANG_C_plus_plus:
        warn("CU %s: C++ not supported", dwarf_diename(cu));
        return false;
        break;
    default:
        debug("CU %s: unsupported language: 0x%lx",
             dwarf_diename(cu), (unsigned long)lang);
        return false;
        break;
    }

    return true;
}
Ejemplo n.º 9
0
static int __die_walk_instances_cb(Dwarf_Die *inst, void *data)
{
	struct __instance_walk_param *iwp = data;
	Dwarf_Attribute attr_mem;
	Dwarf_Die origin_mem;
	Dwarf_Attribute *attr;
	Dwarf_Die *origin;
	int tmp;

	attr = dwarf_attr(inst, DW_AT_abstract_origin, &attr_mem);
	if (attr == NULL)
		return DIE_FIND_CB_CONTINUE;

	origin = dwarf_formref_die(attr, &origin_mem);
	if (origin == NULL || origin->addr != iwp->addr)
		return DIE_FIND_CB_CONTINUE;

	/* Ignore redundant instances */
	if (dwarf_tag(inst) == DW_TAG_inlined_subroutine) {
		dwarf_decl_line(origin, &tmp);
		if (die_get_call_lineno(inst) == tmp) {
			tmp = die_get_decl_fileno(origin);
			if (die_get_call_fileno(inst) == tmp)
				return DIE_FIND_CB_CONTINUE;
		}
	}

	iwp->retval = iwp->callback(inst, iwp->data);

	return (iwp->retval) ? DIE_FIND_CB_END : DIE_FIND_CB_CONTINUE;
}
Ejemplo n.º 10
0
/* Get the size (in words) */
static int get_size(Dwarf_Debug dbg, Dwarf_Die die)
{
    Dwarf_Attribute attr;
    Dwarf_Unsigned size;
    int ret;

    ret = dwarf_attr(die, DW_AT_byte_size, &attr, NULL);
    if (ret != DW_DLV_OK)
    {
        fprintf(stderr, "SET dwarf: Error in dwarf_attr()\n");
        return 1;
    }

    ret = dwarf_formudata(attr, &size, NULL);
    dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
    if (ret != DW_DLV_OK)
    {
        fprintf(stderr, "SET dwarf: Error in dwarf_formudata()\n");
        return 1;
    }

    /* Increment the parameter number of the function */
    func_dwarf[local_func_idx].param_size += (size + 3) >> 2;

    return 0;
}
Ejemplo n.º 11
0
/**
 * die_is_func_def - Ensure that this DIE is a subprogram and definition
 * @dw_die: a DIE
 *
 * Ensure that this DIE is a subprogram and NOT a declaration. This
 * returns true if @dw_die is a function definition.
 **/
bool die_is_func_def(Dwarf_Die *dw_die)
{
	Dwarf_Attribute attr;

	return (dwarf_tag(dw_die) == DW_TAG_subprogram &&
		dwarf_attr(dw_die, DW_AT_declaration, &attr) == NULL);
}
Ejemplo n.º 12
0
static Dwarf_Die get_cu_by_iaddr(unsigned long iaddr){
 
  Dwarf_Unsigned cu_h_len;
  Dwarf_Half verstamp;
  Dwarf_Unsigned abbrev_offset;
  Dwarf_Half addrsize;
  Dwarf_Unsigned next_cu;
  Dwarf_Error error; 
  while( dwarf_next_cu_header(d,
                              &cu_h_len,
                              &verstamp,
                              &abbrev_offset,
                              &addrsize,
                              &next_cu,
                              &error) == DW_DLV_OK ){

    Dwarf_Die cu_die = NULL;
    int sibret;
 
    int dieno = 0; 
    while((sibret = 
           dwarf_siblingof(d,cu_die,&cu_die,&error)) != DW_DLV_NO_ENTRY &&
           sibret                                    != DW_DLV_ERROR){

      Dwarf_Attribute lowattr;
      if( dwarf_attr(cu_die, DW_AT_low_pc, &lowattr, &error) != DW_DLV_OK ){
        continue;
      }
      Dwarf_Attribute highattr;
      if( dwarf_attr(cu_die, DW_AT_high_pc, &highattr, &error) != DW_DLV_OK ){
        continue;
      }

      Dwarf_Addr loval,hival;
      dwarf_formaddr(lowattr,&loval,&error); 
      dwarf_formaddr(highattr,&hival,&error); 
      if(iaddr >= loval && iaddr <= hival){
        return cu_die;
      }

    }

  }
  return (Dwarf_Die)-1;
  
}
Ejemplo n.º 13
0
BT_HIDDEN
int bt_dwarf_die_get_call_file(struct bt_dwarf_die *die, char **filename)
{
	int ret;
	Dwarf_Sword file_no;
	const char *_filename = NULL;
	Dwarf_Files *src_files = NULL;
	Dwarf_Attribute *file_attr = NULL;
	struct bt_dwarf_die *cu_die = NULL;

	if (!die || !filename) {
		goto error;
	}

	file_attr = g_new0(Dwarf_Attribute, 1);
	if (!file_attr) {
		goto error;
	}

	file_attr = dwarf_attr(die->dwarf_die, DW_AT_call_file, file_attr);
	if (!file_attr) {
		goto error;
	}

	ret = dwarf_formsdata(file_attr, &file_no);
	if (ret) {
		goto error;
	}

	cu_die = bt_dwarf_die_create(die->cu);
	if (!cu_die) {
		goto error;
	}

	ret = dwarf_getsrcfiles(cu_die->dwarf_die, &src_files, NULL);
	if (ret) {
		goto error;
	}

	_filename = dwarf_filesrc(src_files, file_no, NULL, NULL);
	if (!_filename) {
		goto error;
	}

	*filename = strdup(_filename);

	bt_dwarf_die_destroy(cu_die);
	g_free(file_attr);

	return 0;

error:
	bt_dwarf_die_destroy(cu_die);
	g_free(file_attr);

	return -1;
}
Ejemplo n.º 14
0
static struct dwarf_subprogram_t *read_from_cus(Dwarf_Debug dbg)
{
    Dwarf_Unsigned cu_header_length, abbrev_offset, next_cu_header;
    Dwarf_Half version_stamp, address_size;
    Dwarf_Error err;
    Dwarf_Die no_die = 0, cu_die, child_die;
    int ret = DW_DLV_OK;
    struct dwarf_subprogram_t *subprograms = NULL;
    Dwarf_Unsigned language = 0;
    Dwarf_Attribute language_attr = 0;

    while (ret == DW_DLV_OK) {
        ret = dwarf_next_cu_header(
                dbg,
                &cu_header_length,
                &version_stamp,
                &abbrev_offset,
                &address_size,
                &next_cu_header,
                &err);
        DWARF_ASSERT(ret, err);

        if (ret == DW_DLV_NO_ENTRY)
            continue;

        /* TODO: If the CU can provide an address range then we can skip over
         * all the entire die if none of our addresses match */

        /* Expect the CU to have a single sibling - a DIE */
        ret = dwarf_siblingof(dbg, no_die, &cu_die, &err);
        if (ret == DW_DLV_ERROR) {
            continue;
        }
        DWARF_ASSERT(ret, err);

        /* Get compilation unit language attribute */
        ret = dwarf_attr(cu_die, DW_AT_language, &language_attr, &err);
        DWARF_ASSERT(ret, err);
        if (ret != DW_DLV_NO_ENTRY) {
            /* Get language attribute data */
            ret = dwarf_formudata(language_attr, &language, &err);
            DWARF_ASSERT(ret, err);
            dwarf_dealloc(dbg, language_attr, DW_DLA_ATTR);
        }

        /* Expect the CU DIE to have children */
        ret = dwarf_child(cu_die, &child_die, &err);
        DWARF_ASSERT(ret, err);

        handle_die(&subprograms, dbg, cu_die, child_die, language);  

        dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
    }

    return subprograms;
}
Ejemplo n.º 15
0
/* Get attribute and translate it as a sdata */
static int die_get_attr_sdata(Dwarf_Die *tp_die, unsigned int attr_name,
			      Dwarf_Sword *result)
{
	Dwarf_Attribute attr;

	if (dwarf_attr(tp_die, attr_name, &attr) == NULL ||
	    dwarf_formsdata(&attr, result) != 0)
		return -ENOENT;

	return 0;
}
Ejemplo n.º 16
0
/**
 * die_get_call_lineno - Get callsite line number of inline-function instance
 * @in_die: a DIE of an inlined function instance
 *
 * Get call-site line number of @in_die. This means from where the inline
 * function is called.
 */
int die_get_call_lineno(Dwarf_Die *in_die)
{
	Dwarf_Attribute attr;
	Dwarf_Word ret;

	if (!dwarf_attr(in_die, DW_AT_call_line, &attr))
		return -ENOENT;

	dwarf_formudata(&attr, &ret);
	return (int)ret;
}
Ejemplo n.º 17
0
static int die_get_byte_size(Dwarf_Die *tp_die)
{
	Dwarf_Attribute attr;
	Dwarf_Word ret;

	if (dwarf_attr(tp_die, DW_AT_byte_size, &attr) == NULL ||
	    dwarf_formudata(&attr, &ret) != 0)
		return 0;

	return (int)ret;
}
Ejemplo n.º 18
0
static bool die_is_signed_type(Dwarf_Die *tp_die)
{
	Dwarf_Attribute attr;
	Dwarf_Word ret;

	if (dwarf_attr(tp_die, DW_AT_encoding, &attr) == NULL ||
	    dwarf_formudata(&attr, &ret) != 0)
		return false;

	return (ret == DW_ATE_signed_char || ret == DW_ATE_signed ||
		ret == DW_ATE_signed_fixed);
}
Ejemplo n.º 19
0
/*
	Return DW_DLV_OK if handling this went ok.
*/
static int
handle_attr_addr(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half attrnum,
		 Dwarf_Error * perr)
{
    int res = DW_DLV_OK;
    Dwarf_Off offset;
    Dwarf_Addr addr;
    Dwarf_Half form;
    int ares;

    Dwarf_Attribute attr;

    ares = dwarf_attr(die, attrnum, &attr, perr);
    if (ares == DW_DLV_OK) {
	int formres = dwarf_whatform(attr, &form, perr);

	switch (formres) {
	case DW_DLV_OK:
	    break;
	case DW_DLV_ERROR:
	case DW_DLV_NO_ENTRY:	/* impossible. */
	    return formres;

	}

	switch (form) {
	case DW_FORM_ref_addr:
	case DW_FORM_addr:
	    res = dwarf_attr_offset(die, attr, &offset, perr);
	    if (res == DW_DLV_OK) {
		ares = dwarf_formaddr(attr, &addr, perr);
		if (ares == DW_DLV_OK) {
		    send_addr_note(DW_SECTION_INFO, offset, addr);
		} else if (ares == DW_DLV_ERROR) {
		    return ares;
		}		/* no entry: ok. */
	    } else {
		res = DW_DLV_ERROR;	/* NO_ENTRY is impossible. */
	    }
	    break;

	default:
	    /* surprising! An error? */

	    ;			/* do nothing */
	}
	dwarf_dealloc(dbg, attr, DW_DLA_ATTR);

    } else {
	res = ares;
    }
    return res;
}
Ejemplo n.º 20
0
static bool MC_dwarf_attr_flag(Dwarf_Die * die, int attribute, bool integrate)
{
  Dwarf_Attribute attr;
  if ((integrate ? dwarf_attr_integrate(die, attribute, &attr)
       : dwarf_attr(die, attribute, &attr)) == 0)
    return false;

  bool result;
  if (dwarf_formflag(&attr, &result))
    xbt_die("Unexpected form for attribute %s",
      simgrid::dwarf::attrname(attribute));
  return result;
}
static int call_probe_finder(Dwarf_Die *sc_die, struct probe_finder *pf)
{
	Dwarf_Attribute fb_attr;
	size_t nops;
	int ret;

	if (!sc_die) {
		pr_err("Caller must pass a scope DIE. Program error.\n");
		return -EINVAL;
	}

	
	if (dwarf_tag(sc_die) != DW_TAG_subprogram) {
		if (!die_find_realfunc(&pf->cu_die, pf->addr, &pf->sp_die)) {
			pr_warning("Failed to find probe point in any "
				   "functions.\n");
			return -ENOENT;
		}
	} else
		memcpy(&pf->sp_die, sc_die, sizeof(Dwarf_Die));

	
	dwarf_attr(&pf->sp_die, DW_AT_frame_base, &fb_attr);
	ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1);
	if (ret <= 0 || nops == 0) {
		pf->fb_ops = NULL;
#if _ELFUTILS_PREREQ(0, 142)
	} else if (nops == 1 && pf->fb_ops[0].atom == DW_OP_call_frame_cfa &&
		   pf->cfi != NULL) {
		Dwarf_Frame *frame;
		if (dwarf_cfi_addrframe(pf->cfi, pf->addr, &frame) != 0 ||
		    dwarf_frame_cfa(frame, &pf->fb_ops, &nops) != 0) {
			pr_warning("Failed to get call frame on 0x%jx\n",
				   (uintmax_t)pf->addr);
			return -ENOENT;
		}
#endif
	}

	
	ret = pf->callback(sc_die, pf);

	
	pf->fb_ops = NULL;

	return ret;
}
Ejemplo n.º 22
0
/* Call probe_finder callback with scope DIE */
static int call_probe_finder(Dwarf_Die *sc_die, struct probe_finder *pf)
{
	Dwarf_Attribute fb_attr;
	size_t nops;
	int ret;

	if (!sc_die) {
		pr_err("Caller must pass a scope DIE. Program error.\n");
		return -EINVAL;
	}

	/* If not a real subprogram, find a real one */
	if (!die_is_func_def(sc_die)) {
		if (!die_find_realfunc(&pf->cu_die, pf->addr, &pf->sp_die)) {
			pr_warning("Failed to find probe point in any "
				   "functions.\n");
			return -ENOENT;
		}
	} else
		memcpy(&pf->sp_die, sc_die, sizeof(Dwarf_Die));

	/* Get the frame base attribute/ops from subprogram */
	dwarf_attr(&pf->sp_die, DW_AT_frame_base, &fb_attr);
	ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1);
	if (ret <= 0 || nops == 0) {
		pf->fb_ops = NULL;
#if _ELFUTILS_PREREQ(0, 142)
	} else if (nops == 1 && pf->fb_ops[0].atom == DW_OP_call_frame_cfa &&
		   pf->cfi != NULL) {
		Dwarf_Frame *frame;
		if (dwarf_cfi_addrframe(pf->cfi, pf->addr, &frame) != 0 ||
		    dwarf_frame_cfa(frame, &pf->fb_ops, &nops) != 0) {
			pr_warning("Failed to get call frame on 0x%jx\n",
				   (uintmax_t)pf->addr);
			return -ENOENT;
		}
#endif
	}

	/* Call finder's callback handler */
	ret = pf->callback(sc_die, pf);

	/* *pf->fb_ops will be cached in libdw. Don't free it. */
	pf->fb_ops = NULL;

	return ret;
}
Ejemplo n.º 23
0
/* Call probe_finder callback with real subprogram DIE */
static int call_probe_finder(Dwarf_Die *sp_die, struct probe_finder *pf)
{
	Dwarf_Die die_mem;
	Dwarf_Attribute fb_attr;
	size_t nops;
	int ret;

	/* If no real subprogram, find a real one */
	if (!sp_die || dwarf_tag(sp_die) != DW_TAG_subprogram) {
		sp_die = die_find_real_subprogram(&pf->cu_die,
						  pf->addr, &die_mem);
		if (!sp_die) {
			pr_warning("Failed to find probe point in any "
				   "functions.\n");
			return -ENOENT;
		}
	}

	/* Get the frame base attribute/ops */
	dwarf_attr(sp_die, DW_AT_frame_base, &fb_attr);
	ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1);
	if (ret <= 0 || nops == 0) {
		pf->fb_ops = NULL;
#if _ELFUTILS_PREREQ(0, 142)
	} else if (nops == 1 && pf->fb_ops[0].atom == DW_OP_call_frame_cfa &&
		   pf->cfi != NULL) {
		Dwarf_Frame *frame;
		if (dwarf_cfi_addrframe(pf->cfi, pf->addr, &frame) != 0 ||
		    dwarf_frame_cfa(frame, &pf->fb_ops, &nops) != 0) {
			pr_warning("Failed to get call frame on 0x%jx\n",
				   (uintmax_t)pf->addr);
			return -ENOENT;
		}
#endif
	}

	/* Call finder's callback handler */
	ret = pf->callback(sp_die, pf);

	/* *pf->fb_ops will be cached in libdw. Don't free it. */
	pf->fb_ops = NULL;

	return ret;
}
static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
{
	struct dwarf_callback_param *param = data;
	struct probe_finder *pf = param->data;
	struct perf_probe_point *pp = &pf->pev->point;
	Dwarf_Attribute attr;

	
	if (dwarf_tag(sp_die) != DW_TAG_subprogram ||
	    !die_compare_name(sp_die, pp->function) ||
	    dwarf_attr(sp_die, DW_AT_declaration, &attr))
		return DWARF_CB_OK;

	
	if (pp->file && strtailcmp(pp->file, dwarf_decl_file(sp_die)))
		return DWARF_CB_OK;

	pf->fname = dwarf_decl_file(sp_die);
	if (pp->line) { 
		dwarf_decl_line(sp_die, &pf->lno);
		pf->lno += pp->line;
		param->retval = find_probe_point_by_line(pf);
	} else if (!dwarf_func_inline(sp_die)) {
		
		if (pp->lazy_line)
			param->retval = find_probe_point_lazy(sp_die, pf);
		else {
			if (dwarf_entrypc(sp_die, &pf->addr) != 0) {
				pr_warning("Failed to get entry address of "
					   "%s.\n", dwarf_diename(sp_die));
				param->retval = -ENOENT;
				return DWARF_CB_ABORT;
			}
			pf->addr += pp->offset;
			
			param->retval = call_probe_finder(sp_die, pf);
		}
	} else
		
		param->retval = die_walk_instances(sp_die,
					probe_point_inline_cb, (void *)pf);

	return DWARF_CB_ABORT; 
}
Ejemplo n.º 25
0
static void
tp_dwarf_attr_sanity(void)
{
	Dwarf_Debug dbg;
	Dwarf_Error de;
	Dwarf_Bool has_attr;
	Dwarf_Half attr;
	Dwarf_Attribute at;
	int fd;

	result = TET_UNRESOLVED;

	TS_DWARF_INIT(dbg, fd, de);

	if (dwarf_hasattr(NULL, DW_AT_name, &has_attr, &de) != DW_DLV_ERROR) {
		tet_infoline("dwarf_hasattr didn't return DW_DLV_ERROR"
		    " when called with NULL arguments");
		result = TET_FAIL;
		goto done;
	}

	if (dwarf_attr(NULL, DW_AT_name, &at, &de) != DW_DLV_ERROR) {
		tet_infoline("dwarf_attr didn't return DW_DLV_ERROR"
		    " when called with NULL arguments");
		result = TET_FAIL;
		goto done;
	}

	if (dwarf_whatattr(NULL, &attr, &de) != DW_DLV_ERROR) {
		tet_infoline("dwarf_whatattr didn't return DW_DLV_ERROR"
		    " when called with NULL arguments");
		result = TET_FAIL;
		goto done;
	}

	if (result == TET_UNRESOLVED)
		result = TET_PASS;

done:
	TS_DWARF_FINISH(dbg, de);
	TS_RESULT(result);
}
Ejemplo n.º 26
0
/* Get type die, but skip qualifiers and typedef */
static Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
{
	Dwarf_Attribute attr;
	int tag;

	do {
		if (dwarf_attr(vr_die, DW_AT_type, &attr) == NULL ||
		    dwarf_formref_die(&attr, die_mem) == NULL)
			return NULL;

		tag = dwarf_tag(die_mem);
		vr_die = die_mem;
	} while (tag == DW_TAG_const_type ||
		 tag == DW_TAG_restrict_type ||
		 tag == DW_TAG_volatile_type ||
		 tag == DW_TAG_shared_type ||
		 tag == DW_TAG_typedef);

	return die_mem;
}
Ejemplo n.º 27
0
int type_off(Dwarf_Die *die, Dwarf_Off *ref_off, Dwarf_Error *err) {
  Dwarf_Attribute type;
  int status;

  if ((status = dwarf_attr(*die, DW_AT_type, &type, err)) != DW_DLV_OK) {
    if (status == DW_DLV_NO_ENTRY) {
      fprintf(stderr, "No type information associated with die\n");
    } else {
      fprintf(stderr, "Error %d in getting type attribute: %s\n", status,
              dwarf_errmsg(*err));
    }
    return status;
  }

  if ((status = dwarf_global_formref(type, ref_off, err)) != DW_DLV_OK) {
    fprintf(stderr, "Error %d in getting type offset: %s\n", status,
            dwarf_errmsg(*err));
    return status;
  }

  return DW_DLV_OK;
}
Ejemplo n.º 28
0
long get_location_of_scoped_variable(void *addr,const char * varname){

  Dwarf_Error error;
  unsigned long a = (unsigned long)addr;

  reset_cu_header_info();

  Dwarf_Die cu = get_cu_by_iaddr(a);

  reset_cu_header_info();

  if(a != 0xffffffffffffffff && (long int)cu != -1){

    Dwarf_Die v;
    v = (Dwarf_Die)0; 
    DC_get_info_for_scoped_variable(cu,0,a,varname,&v);
    if( v != (Dwarf_Die)-1 ){

      Dwarf_Attribute loc;
      dwarf_attr(v,DW_AT_location,&loc,&error);

      DC_location dloc;
      DC_get_location_attr_value(loc,&dloc);



      
      return dloc.offset;
    }

  }else{

    fprintf(stderr,"Can't find \"%s\" in scope defined by <%x>\n",varname, a);

  }

  fprintf(stderr,"\n");

}
Ejemplo n.º 29
0
static Dwarf_Attribute
die_attr(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, int req)
{
	Dwarf_Attribute attr;
	int rc;

	if ((rc = dwarf_attr(die, name, &attr, &dw->dw_err)) == DW_DLV_OK) {
		return (attr);
	} else if (rc == DW_DLV_NO_ENTRY) {
		if (req) {
			terminate("die %llu: no attr 0x%x\n", die_off(dw, die),
			    name);
		} else {
			return (NULL);
		}
	}

	terminate("die %llu: failed to get attribute for type: %s\n",
	    die_off(dw, die), dwarf_errmsg(dw->dw_err));
	/*NOTREACHED*/
	return (NULL);
}
Ejemplo n.º 30
0
/* Show a variables in kprobe event format */
static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
{
	Dwarf_Attribute attr;
	Dwarf_Die die_mem;
	Dwarf_Op *expr;
	size_t nexpr;
	int ret;

	if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL)
		goto error;
	/* TODO: handle more than 1 exprs */
	ret = dwarf_getlocation_addr(&attr, pf->addr, &expr, &nexpr, 1);
	if (ret <= 0 || nexpr == 0)
		goto error;

	ret = convert_location(expr, pf);
	if (ret == 0 && pf->pvar->field) {
		ret = convert_variable_fields(vr_die, pf->pvar->var,
					      pf->pvar->field, &pf->tvar->ref,
					      &die_mem);
		vr_die = &die_mem;
	}
	if (ret == 0) {
		if (pf->pvar->type) {
			pf->tvar->type = strdup(pf->pvar->type);
			if (pf->tvar->type == NULL)
				ret = -ENOMEM;
		} else
			ret = convert_variable_type(vr_die, pf->tvar);
	}
	/* *expr will be cached in libdw. Don't free it. */
	return ret;
error:
	/* TODO: Support const_value */
	pr_err("Failed to find the location of %s at this address.\n"
	       " Perhaps, it has been optimized out.\n", pf->pvar->var);
	return -ENOENT;
}