Ejemplo n.º 1
0
static void handle_die(
        struct dwarf_subprogram_t **subprograms,
        Dwarf_Debug dbg, Dwarf_Die cu_die, Dwarf_Die the_die, Dwarf_Unsigned language)
{
    int rc;
    Dwarf_Error err;
    Dwarf_Die current_die = the_die;
    Dwarf_Die child_die = NULL;
    Dwarf_Die next_die;

    do {
        *subprograms = read_cu_entry(*subprograms, dbg, cu_die, current_die, language);

        /* Recursive call handle_die with child, to continue searching within child dies */
        rc = dwarf_child(current_die, &child_die, &err);
        DWARF_ASSERT(rc, err);
        if (rc == DW_DLV_OK && child_die)
            handle_die(subprograms, dbg, cu_die, child_die, language);    

        rc = dwarf_siblingof(dbg, current_die, &next_die, &err);
        DWARF_ASSERT(rc, err);

        dwarf_dealloc(dbg, current_die, DW_DLA_DIE);

        current_die = next_die;
    } while (rc != DW_DLV_NO_ENTRY);
}
Ejemplo n.º 2
0
BT_HIDDEN
int bt_dwarf_die_child(struct bt_dwarf_die *die)
{
	int ret;
	Dwarf_Die *child_die = NULL;

	if (!die) {
		ret = -1;
		goto error;
	}

	child_die = g_new0(Dwarf_Die, 1);
	if (!child_die) {
		ret = -1;
		goto error;
	}

	ret = dwarf_child(die->dwarf_die, child_die);
	if (ret) {
		/* ret is -1 on error, 1 if no child DIE. */
		goto error;
	}

	g_free(die->dwarf_die);
	die->dwarf_die = child_die;
	die->depth++;
	return 0;

error:
	g_free(child_die);
	return ret;
}
Ejemplo n.º 3
0
struct variable* child_variables(Dwarf_Die *parent, Dwarf_Files *files,
                                 struct expr_context *ctx, bool params)
{
    int ret;
    Dwarf_Die die;
    struct variable *var, *head = NULL, *tail = NULL;
    int desired_tag = params ? DW_TAG_formal_parameter : DW_TAG_variable;

    ret = dwarf_child(parent, &die);
    if (ret != 0)
        return NULL;

    do
    {
        if (dwarf_tag(&die) == desired_tag)
        {
            var = analyze_variable(&die, files, ctx);
            if (!var)
                continue;

            list_append(head, tail, var);
        }
    } while (dwarf_siblingof(&die, &die) == 0);

    return head;
}
Ejemplo n.º 4
0
/**
 * die_find_child - Generic DIE search function in DIE tree
 * @rt_die: a root DIE
 * @callback: a callback function
 * @data: a user data passed to the callback function
 * @die_mem: a buffer for result DIE
 *
 * Trace DIE tree from @rt_die and call @callback for each child DIE.
 * If @callback returns DIE_FIND_CB_END, this stores the DIE into
 * @die_mem and returns it. If @callback returns DIE_FIND_CB_CONTINUE,
 * this continues to trace the tree. Optionally, @callback can return
 * DIE_FIND_CB_CHILD and DIE_FIND_CB_SIBLING, those means trace only
 * the children and trace only the siblings respectively.
 * Returns NULL if @callback can't find any appropriate DIE.
 */
Dwarf_Die *die_find_child(Dwarf_Die *rt_die,
			  int (*callback)(Dwarf_Die *, void *),
			  void *data, Dwarf_Die *die_mem)
{
	Dwarf_Die child_die;
	int ret;

	ret = dwarf_child(rt_die, die_mem);
	if (ret != 0)
		return NULL;

	do {
		ret = callback(die_mem, data);
		if (ret == DIE_FIND_CB_END)
			return die_mem;

		if ((ret & DIE_FIND_CB_CHILD) &&
		    die_find_child(die_mem, callback, data, &child_die)) {
			memcpy(die_mem, &child_die, sizeof(Dwarf_Die));
			return die_mem;
		}
	} while ((ret & DIE_FIND_CB_SIBLING) &&
		 dwarf_siblingof(die_mem, die_mem) == 0);

	return NULL;
}
Ejemplo n.º 5
0
/* Recursively follow the DIE tree */
static int process_die_and_children(Dwarf_Debug dbg, Dwarf_Die in_die)
{
    Dwarf_Die cur_die = in_die;
    Dwarf_Die child;
    Dwarf_Die sib_die;
    int is_function;
    int ret;

    ret = process_one_DIE(dbg, in_die, &is_function);
    if (ret != 0)
        return 1;

    while (1)
    {
        if (!is_function)   /* Assume that there is no nested function, so we ignore the children of a function */ 
        {
            ret = dwarf_child(cur_die, &child, NULL);
            if (ret == DW_DLV_ERROR)
            {
                fprintf(stderr, "SET dwarf: Error in dwarf_child()\n");
                return 1;
            }

            /* Recursive call */
            if (ret == DW_DLV_OK)
            {
                ret = process_die_and_children(dbg, child);
                dwarf_dealloc(dbg, child, DW_DLA_DIE);
                if (ret != 0)
                    return 1;
            }
        }

        /* Current DIE has no children */
        ret = dwarf_siblingof(dbg, cur_die, &sib_die, NULL);
        if (ret == DW_DLV_ERROR)
        {
            fprintf(stderr, "SET dwarf: Error in dwarf_siblingof()\n");
            return 1;
        }

        if (cur_die != in_die)
            dwarf_dealloc(dbg, cur_die, DW_DLA_DIE);

        if (ret == DW_DLV_NO_ENTRY)
        {
            /* Done at this level */
            break;
        }

        /* ret == DW_DLV_OK */
        cur_die = sib_die;
        ret = process_one_DIE(dbg, cur_die, &is_function);
        if (ret != 0)
            return 1;
    }
    return 0;
}
Ejemplo n.º 6
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, next_die;
    int ret = DW_DLV_OK;
    int rc;
    struct dwarf_subprogram_t *subprograms = NULL;

    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);

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

        next_die = child_die;

        /* Now go over all children DIEs */
        do {
            subprograms = read_cu_entry(subprograms, dbg, cu_die, child_die);

            rc = dwarf_siblingof(dbg, child_die, &next_die, &err);
            DWARF_ASSERT(rc, err);

            dwarf_dealloc(dbg, child_die, DW_DLA_DIE);

            child_die = next_die;
        } while (rc != DW_DLV_NO_ENTRY);

        dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
    }

    return subprograms;
}
Ejemplo n.º 7
0
static void DC_show_info_for_containing_pc_ranges(Dwarf_Die die, int enclosing, unsigned long iaddr){

  /*This function visits the children of a die in sequence, 
   *applying the action() function to each*/
  Dwarf_Attribute highattr;
  Dwarf_Attribute lowattr;
  Dwarf_Addr loval,hival;
  Dwarf_Bool has;
  Dwarf_Error error;
  Dwarf_Half tag; 
  
  loval = hival = 0x0;
  int enc = 0;

  dwarf_tag(die,&tag,&error);
 
  if( tag == DW_TAG_variable ||
      tag == DW_TAG_formal_parameter ){

    if(enclosing){
      char *name;
      dwarf_diename(die,&name,&error);
      fprintf(stderr,"%s, ",name);
      //show_all_attrs(die,0,NULL);
    }
     
  }

  if( tag == DW_TAG_lexical_block || tag == DW_TAG_subprogram ){
    if( dwarf_lowpc(die,&loval,&error) == DW_DLV_OK  && dwarf_highpc(die,&hival,&error) == DW_DLV_OK
        && iaddr >=loval && iaddr <= hival ){ 
      enc = 1;
      fprintf(stderr,"\n=================================\n");
      show_all_attrs(die,0,NULL);
      fprintf(stderr,"=================================\n");
    }
  
  }
  
  Dwarf_Die kid;
  if( dwarf_child(die,&kid,&error) == DW_DLV_NO_ENTRY ){
    return;
  }
  DC_show_info_for_containing_pc_ranges(kid, enc, iaddr); 
  //visit_die(kid,level+1,action,adata); 

  int chret;
  while( (chret = dwarf_siblingof(d,kid,&kid,&error)) != DW_DLV_NO_ENTRY &&
           chret != DW_DLV_ERROR){

    DC_show_info_for_containing_pc_ranges(kid, enc, iaddr); 
    //visit_die(kid,level+1,action,adata);

  }

  return;
}
Ejemplo n.º 8
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.º 9
0
static void DC_get_info_for_scoped_variable(Dwarf_Die die, int enclosing, unsigned long iaddr, const char *varname, Dwarf_Die *retDie){

  /*This function visits the children of a die in sequence, 
   *applying the action() function to each*/
  Dwarf_Attribute highattr;
  Dwarf_Attribute lowattr;
  Dwarf_Addr loval,hival;
  Dwarf_Bool has;
  Dwarf_Error error;
  Dwarf_Half tag; 
  
  loval = hival = 0x0;
  int enc = 0;

  dwarf_tag(die,&tag,&error);
 
  if( tag == DW_TAG_variable ||
      tag == DW_TAG_formal_parameter ){

    if(enclosing){
      char *name;
      dwarf_diename(die,&name,&error);
      if(!strncmp(name,varname,strlen(name))){
        *retDie = die;
        return;
      }
    }
     
  }

  if( tag == DW_TAG_lexical_block || tag == DW_TAG_subprogram ){
    if( dwarf_lowpc(die,&loval,&error) == DW_DLV_OK  && dwarf_highpc(die,&hival,&error) == DW_DLV_OK
        && iaddr >=loval && iaddr <= hival ){ 
      enc = 1;
    }
  
  }
  
  Dwarf_Die kid;
  if( dwarf_child(die,&kid,&error) == DW_DLV_NO_ENTRY ){
    return;
  }
  DC_get_info_for_scoped_variable(kid, enc, iaddr,varname,retDie); 

  int chret;
  while( (chret = dwarf_siblingof(d,kid,&kid,&error)) != DW_DLV_NO_ENTRY &&
           chret != DW_DLV_ERROR){

    DC_get_info_for_scoped_variable(kid, enc, iaddr,varname,retDie); 

  }

  return;

}
Ejemplo n.º 10
0
Dwarf_Die DieHolder::get_child(void)
{
  Dwarf_Die child_die = NULL;
  Dwarf_Error err = NULL;

  // there may be no child
  CHECK_DWERR2(dwarf_child(m_die, &child_die, &err) == DW_DLV_ERROR, err,
               "error when asking for a DIE child");

  return child_die;
}
Ejemplo n.º 11
0
static void MC_dwarf_handle_children(simgrid::mc::ObjectInformation* info, Dwarf_Die * die,
                                     Dwarf_Die * unit, simgrid::mc::Frame* frame,
                                     const char *ns)
{
  // For each child DIE:
  Dwarf_Die child;
  int res;
  for (res = dwarf_child(die, &child); res == 0;
       res = dwarf_siblingof(&child, &child))
    MC_dwarf_handle_die(info, &child, unit, frame, ns);
}
Ejemplo n.º 12
0
static void
print_vars (unsigned int indent, Dwarf_Die *die)
{
  Dwarf_Die child;
  if (dwarf_child (die, &child) == 0)
    do
      switch (dwarf_tag (&child))
	{
	case DW_TAG_variable:
	case DW_TAG_formal_parameter:
	  printf ("%*s%-30s[%6" PRIx64 "]\n", indent, "",
		  dwarf_diename (&child),
		  (uint64_t) dwarf_dieoffset (&child));
	  break;
	default:
	  break;
	}
    while (dwarf_siblingof (&child, &child) == 0);

  Dwarf_Attribute attr_mem;
  Dwarf_Die origin;
  if (dwarf_hasattr (die, DW_AT_abstract_origin)
      && dwarf_formref_die (dwarf_attr (die, DW_AT_abstract_origin, &attr_mem),
			    &origin) != NULL
      && dwarf_child (&origin, &child) == 0)
    do
      switch (dwarf_tag (&child))
	{
	case DW_TAG_variable:
	case DW_TAG_formal_parameter:
	  printf ("%*s%s (abstract)\n", indent, "",
		  dwarf_diename (&child));
	  break;
	default:
	  break;
	}
    while (dwarf_siblingof (&child, &child) == 0);
}
Ejemplo n.º 13
0
static Dwarf_Die
die_child(dwarf_t *dw, Dwarf_Die die)
{
	Dwarf_Die child;
	int rc;

	if ((rc = dwarf_child(die, &child, &dw->dw_err)) == DW_DLV_OK)
		return (child);
	else if (rc == DW_DLV_NO_ENTRY)
		return (NULL);

	terminate("die %llu: failed to find type child: %s\n",
	    die_off(dw, die), dwarf_errmsg(dw->dw_err));
	/*NOTREACHED*/
	return (NULL);
}
static void
get_die_and_siblings(Dwarf_Debug dbg, Dwarf_Die in_die,int in_level,
   struct srcfilesdata *sf)
{
    int res = DW_DLV_ERROR;
    Dwarf_Die cur_die=in_die;
    Dwarf_Die child = 0;
    Dwarf_Error error;
   
    print_die_data(dbg,in_die,in_level,sf);

    for(;;) {

        /*edit by liupo*/
        //printf("\n-----------SIB-%d----------------\n", in_level);
        /*end edit*/

        Dwarf_Die sib_die = 0;
        res = dwarf_child(cur_die,&child,&error);
        if(res == DW_DLV_ERROR) {
            printf("Error in dwarf_child , level %d \n",in_level);
            exit(1);
        }
        if(res == DW_DLV_OK) {
            get_die_and_siblings(dbg,child,in_level+1,sf);
        }
        /* res == DW_DLV_NO_ENTRY */
        res = dwarf_siblingof(dbg,cur_die,&sib_die,&error);
        if(res == DW_DLV_ERROR) {
            printf("Error in dwarf_siblingof , level %d \n",in_level);
            exit(1);
        }
        if(res == DW_DLV_NO_ENTRY) {
            /* Done at this level. */
            break;
        }
        /* res == DW_DLV_OK */
        if(cur_die != in_die) {
            dwarf_dealloc(dbg,cur_die,DW_DLA_DIE);
        }
        cur_die = sib_die;
        print_die_data(dbg,cur_die,in_level,sf);
    }
    return;
}
Ejemplo n.º 15
0
void print_die_rec(Dwarf_Die *die, int lvl)
{
	int ret;
	Dwarf_Die chdie, sdie;

	if (!die)
		return;

	print_dbg_info(die, lvl);

	ret = dwarf_child(die, &chdie);
	if (!ret)
		print_die_rec(&chdie, lvl+1);

	ret = dwarf_siblingof(die, &sdie);
	if (!ret)
		print_die_rec(&sdie, lvl);
}
Ejemplo n.º 16
0
/** \brief Finds the number of elements in a array type (DW_TAG_array_type)
 *
 *  The compilation unit might be needed because the default lower
 *  bound depends on the language of the compilation unit.
 *
 *  \param die the DIE of the DW_TAG_array_type
 *  \param unit the DIE of the compilation unit
 *  \return number of elements in this array type
 * */
static uint64_t MC_dwarf_array_element_count(Dwarf_Die * die, Dwarf_Die * unit)
{
  xbt_assert(dwarf_tag(die) == DW_TAG_array_type,
             "MC_dwarf_array_element_count called with DIE of type %s",
             simgrid::dwarf::tagname(die));

  int result = 1;
  Dwarf_Die child;
  int res;
  for (res = dwarf_child(die, &child); res == 0;
       res = dwarf_siblingof(&child, &child)) {
    int child_tag = dwarf_tag(&child);
    if (child_tag == DW_TAG_subrange_type
        || child_tag == DW_TAG_enumeration_type)
      result *= MC_dwarf_subrange_element_count(&child, unit);
  }
  return result;
}
Ejemplo n.º 17
0
BT_HIDDEN
int bt_dwarf_die_next(struct bt_dwarf_die *die)
{
	int ret;
	Dwarf_Die *next_die = NULL;

	if (!die) {
		ret = -1;
		goto error;
	}

	next_die = g_new0(Dwarf_Die, 1);
	if (!next_die) {
		ret = -1;
		goto error;
	}

	if (die->depth == 0) {
		ret = dwarf_child(die->dwarf_die, next_die);
		if (ret) {
			/* ret is -1 on error, 1 if no child DIE. */
			goto error;
		}

		die->depth = 1;
	} else {
		ret = dwarf_siblingof(die->dwarf_die, next_die);
		if (ret) {
			/* ret is -1 on error, 1 if we reached end of
			 * DIEs at this depth. */
			goto error;
		}
	}

	g_free(die->dwarf_die);
	die->dwarf_die = next_die;
	return 0;

error:
	g_free(next_die);
	return ret;
}
Ejemplo n.º 18
0
error_t find_var_die(mygdb_info_t* gdb_info, Dwarf_Die func_die, char* var_name){
	Dwarf_Half tag;
	Dwarf_Error err;
	Dwarf_Die child_die;
	/* Find compilation unit header */

	if (dwarf_tag(func_die, &tag, &err) != DW_DLV_OK)
		return E_FATAL;

	/* Can't find var if this isn't a func_die */
	if (tag != DW_TAG_subprogram)
		return E_FATAL; //

	/* Expect the CU DIE to have children */
	if (dwarf_child(func_die, &child_die, &err) == DW_DLV_ERROR)
		return E_FATAL;
	
	/* Now go over all children DIEs */
	while (1) {
		int rc;
		bool found = false;
		
		if( is_right_var(child_die, var_name, &found) == E_FATAL)
			return E_FATAL;

		if(found){
			return print_local_var(gdb_info, child_die, var_name);
		}
	
		rc = dwarf_siblingof(gdb_info->dbg, child_die, &child_die, &err);	
	
		if (rc == DW_DLV_ERROR)
			return E_FATAL;	
		else if (rc == DW_DLV_NO_ENTRY){
			printf("Couldn't find var named: %s\n", var_name);
			return E_NON_FATAL; //var not found!
		}
	}


	return E_FATAL; //if reached here, didnt find var and didnt hit end of dies list
}					//must have broken something
Ejemplo n.º 19
0
static void
tp_dwarf_child_first(void)
{
	Dwarf_Debug dbg;
	Dwarf_Error de;
	Dwarf_Die die, die0;
	Dwarf_Unsigned cu_next_offset;
	int r, fd, result, die_cnt;

	result = TET_UNRESOLVED;

	TS_DWARF_INIT(dbg, fd, de);

	tet_infoline("count the number of children of compilation unit DIE");

	die_cnt = 0;
	TS_DWARF_CU_FOREACH(dbg, cu_next_offset, de) {
		r = dwarf_siblingof(dbg, NULL, &die, &de);
		if (r == DW_DLV_OK) {
			r = dwarf_child(die, &die0, &de);
			while (r == DW_DLV_OK) {
				if (die0 == NULL) {
					tet_infoline("dwarf_child or "
					    "dwarf_siblingof return "
					    "DW_DLV_OK while argument die0 "
					    "is not filled in");
					result = TET_FAIL;
					goto done;
				}
				die_cnt++;
				die = die0;
				r = dwarf_siblingof(dbg, die, &die0, &de);
			}
		}
		if (r == DW_DLV_ERROR) {
			tet_printf("dwarf_siblingof or dwarf_child failed:"
			    " %s\n", dwarf_errmsg(de));
			result = TET_FAIL;
			goto done;
		}
	}
Ejemplo n.º 20
0
void DwarfDie::scanChildren() const
{
    m_childrenScanned = true;

    Dwarf_Die childDie;
    auto res = dwarf_child(m_die, &childDie, nullptr);
    if (res != DW_DLV_OK)
        return;

    const auto handle = dwarfHandle();
    forever {
        m_children.push_back(new DwarfDie(childDie, const_cast<DwarfDie*>(this)));

        Dwarf_Die siblingDie;
        res = dwarf_siblingof(handle, childDie, &siblingDie, nullptr);
        if (res != DW_DLV_OK)
            return;

        childDie = siblingDie;
    }
}
Ejemplo n.º 21
0
/* List all the functions from the file represented by the given descriptor.
*/
void list_funcs_in_file(Dwarf_Debug dbg, FILE *fp)
{
    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;

    /* Find compilation unit header */
    if (dwarf_next_cu_header(
                dbg,
                &cu_header_length,
                &version_stamp,
                &abbrev_offset,
                &address_size,
                &next_cu_header,
                &err) == DW_DLV_ERROR)
        die("Error reading DWARF cu header\n");

    /* Expect the CU to have a single sibling - a DIE */
    if (dwarf_siblingof(dbg, no_die, &cu_die, &err) == DW_DLV_ERROR)
        die("Error getting sibling of CU\n");

    /* Expect the CU DIE to have children */
    if (dwarf_child(cu_die, &child_die, &err) == DW_DLV_ERROR)
        die("Error getting child of CU DIE\n");

    /* Now go over all children DIEs */
    while (1) {
        int rc;
        list_func_in_die(dbg, child_die, fp);

        rc = dwarf_siblingof(dbg, child_die, &child_die, &err);

        if (rc == DW_DLV_ERROR)
            die("Error getting sibling of DIE\n");
        else if (rc == DW_DLV_NO_ENTRY)
            break; /* done */
    }
}
Ejemplo n.º 22
0
error_t find_func_die(mygdb_info_t* gdb_info, Dwarf_Die* ret_die){
	Dwarf_Error err;
	//Dwarf_Die child_die;
	/* Find compilation unit header */

	/* Expect the CU DIE to have children */
	if (dwarf_child(gdb_info->cu_die, ret_die, &err) == DW_DLV_ERROR)
		return E_FATAL;

	struct user_regs_struct regs;
	if( ptrace(PTRACE_GETREGS, gdb_info->child_pid, NULL, &regs) < 0)
		return E_FATAL;
	

	/* Now go over all children DIEs */
	while (1) {
		int rc;
		bool found = false;
		if( ip_in_func(*ret_die, regs.rip - 1, &found) == E_FATAL)
			return E_FATAL;

		if(found){
			return E_NONE;
		}
	
		rc = dwarf_siblingof(gdb_info->dbg, *ret_die, ret_die, &err);	
	
		if (rc == DW_DLV_ERROR)
			return E_FATAL;	
		else if (rc == DW_DLV_NO_ENTRY){
			return E_FATAL; //Func not found!
		}
	}

	return E_FATAL; // didnt find func

}
Dwarf_Die dwarf_get_next_function(Dwarf_Die previous_die, struct dwarf_compilation_unit * unit){

  Dwarf_Half tag = 0;
  Dwarf_Error error;
  Dwarf_Die func_die=0;

  //first, see what type this is
  dwarf_tag(previous_die,&tag,&error);
  if (tag == DW_TAG_compile_unit){
    //if its the first child, make sure its not a subprogram
    int res = dwarf_child(unit->root_die,&previous_die,&error);
    dwarf_tag(previous_die,&tag,&error);
    //is it a subprogram, if so we are done
    if (tag == DW_TAG_subprogram){
      return previous_die;
    }
  }
  func_die = _get_next_function_helper(previous_die, unit->dbg);
  if (func_die > 0){
    return func_die;
  }

  return NULL;
}
static Dwarf_Die _get_next_variable(Dwarf_Die die, Dwarf_Die original_die, struct dwarf_compilation_unit * unit){
  Dwarf_Die sib_die = 0;
  Dwarf_Die child = 0;
  Dwarf_Half tag = 0;
  Dwarf_Error error;
  int res;
  //first, see what type this is
  dwarf_tag(die,&tag,&error);
  if ((tag == DW_TAG_variable || tag == DW_TAG_formal_parameter) && die != original_die){
    return die;
  }

  //go through each child
  res = dwarf_child(die,&child,&error);
  if(res == DW_DLV_OK) {
    Dwarf_Die result = _get_next_variable(child,original_die,unit);
    if (result > 0){
      return result;
    }
  }
  
  //now do the siblings
  res = dwarf_siblingof(unit->dbg,die,&sib_die,&error);
  Dwarf_Die old_die = 0;
  while(res != DW_DLV_ERROR && (old_die != sib_die)){
    old_die=sib_die;
    if(res ==  DW_DLV_OK) {
      dwarf_tag(sib_die,&tag,&error);
      if (tag == DW_TAG_variable || tag == DW_TAG_formal_parameter){
	return sib_die;
      }
      res = dwarf_siblingof(unit->dbg,sib_die,&sib_die,&error);
    }
  }
  return NULL;
}
Ejemplo n.º 25
0
static void visit_die(Dwarf_Die die, unsigned long level, void (*action)(Dwarf_Die,unsigned long, void *d),void *adata){

  /*This function visits the children of a die in sequence, 
   *applying the action() function to each*/
  action(die,level,adata);
 
  Dwarf_Error error; 
  Dwarf_Die kid;
  if( dwarf_child(die,&kid,&error) == DW_DLV_NO_ENTRY ){
    return;
  }
  visit_die(kid,level+1,action,adata); 

  int chret;
  while( (chret = dwarf_siblingof(d,kid,&kid,&error)) != DW_DLV_NO_ENTRY &&
           chret != DW_DLV_ERROR){

    visit_die(kid,level+1,action,adata);

  }

  return;
  
}
Ejemplo n.º 26
0
Archivo: rdwarf.c Proyecto: kubo/rdwarf
static VALUE rd_die_children(VALUE self)
{
    rd_die_t *die = GetDie(self);
    VALUE top;
    VALUE cu;
    VALUE ary;
    Dwarf_Die child;
    Dwarf_Error err;

    if (die->children != Qfalse) {
        return die->children;
    }

    top = rb_ivar_get(self, id_at_top);
    cu = rb_ivar_get(self, id_at_cu);
    ary = rb_ary_new();
    if (chkerr2(dwarf_child(die->die, &child, &err), &err)) {
        do {
            rb_ary_push(ary, rd_die_new(die->shared_data, top, cu, child));
        } while (chkerr2(dwarf_siblingof(die->shared_data->dbg, child, &child, &err), &err));
    }
    die->children = ary;
    return ary;
}
Ejemplo n.º 27
0
/* If this type is an HFA small enough to be returned in FP registers,
   return the number of registers to use.  Otherwise 9, or -1 for errors.  */
static int
hfa_type (Dwarf_Die *typedie, Dwarf_Word size,
	  const Dwarf_Op **locp, int fpregs_used)
{
  /* Descend the type structure, counting elements and finding their types.
     If we find a datum that's not an FP type (and not quad FP), punt.
     If we find a datum that's not the same FP type as the first datum, punt.
     If we count more than eight total homogeneous FP data, punt.  */

  inline int hfa (const Dwarf_Op *loc, int nregs)
    {
      if (fpregs_used == 0)
	*locp = loc;
      else if (*locp != loc)
	return 9;
      return fpregs_used + nregs;
    }

  int tag = DWARF_TAG_OR_RETURN (typedie);
  switch (tag)
    {
      Dwarf_Attribute attr_mem;

    case -1:
      return -1;

    case DW_TAG_base_type:;
      Dwarf_Word encoding;
      if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
						 &attr_mem), &encoding) != 0)
	return -1;

      switch (encoding)
	{
	case DW_ATE_float:
	  switch (size)
	    {
	    case 4:		/* float */
	      return hfa (loc_fpreg_4, 1);
	    case 8:		/* double */
	      return hfa (loc_fpreg_8, 1);
	    case 10:       /* x86-style long double, not really used */
	      return hfa (loc_fpreg_10, 1);
	    }
	  break;

	case DW_ATE_complex_float:
	  switch (size)
	    {
	    case 4 * 2:	/* complex float */
	      return hfa (loc_fpreg_4, 2);
	    case 8 * 2:	/* complex double */
	      return hfa (loc_fpreg_8, 2);
	    case 10 * 2:	/* complex long double (x86-style) */
	      return hfa (loc_fpreg_10, 2);
	    }
	  break;
	}
      break;

    case DW_TAG_structure_type:
    case DW_TAG_class_type:
    case DW_TAG_union_type:;
      Dwarf_Die child_mem;
      switch (dwarf_child (typedie, &child_mem))
	{
	default:
	  return -1;

	case 1:			/* No children: empty struct.  */
	  break;

	case 0:;		/* Look at each element.  */
	  int max_used = fpregs_used;
	  do
	    switch (dwarf_tag (&child_mem))
	      {
	      case -1:
		return -1;

	      case DW_TAG_member:;
		Dwarf_Die child_type_mem;
		Dwarf_Die *child_typedie
		  = dwarf_formref_die (dwarf_attr_integrate (&child_mem,
							     DW_AT_type,
							     &attr_mem),
				       &child_type_mem);
		Dwarf_Word child_size;
		if (dwarf_aggregate_size (child_typedie, &child_size) != 0)
		  return -1;
		if (tag == DW_TAG_union_type)
		  {
		    int used = hfa_type (child_typedie, child_size,
					 locp, fpregs_used);
		    if (used < 0 || used > 8)
		      return used;
		    if (used > max_used)
		      max_used = used;
		  }
		else
		  {
		    fpregs_used = hfa_type (child_typedie, child_size,
					    locp, fpregs_used);
		    if (fpregs_used < 0 || fpregs_used > 8)
		      return fpregs_used;
		  }
	      }
	  while (dwarf_siblingof (&child_mem, &child_mem) == 0);
	  if (tag == DW_TAG_union_type)
	    fpregs_used = max_used;
	  break;
	}
      break;

    case DW_TAG_array_type:
      if (size == 0)
	break;

      Dwarf_Die base_type_mem;
      Dwarf_Die *base_typedie
	= dwarf_formref_die (dwarf_attr_integrate (typedie, DW_AT_type,
						   &attr_mem),
			     &base_type_mem);
      Dwarf_Word base_size;
      if (dwarf_aggregate_size (base_typedie, &base_size) != 0)
	return -1;

      int used = hfa_type (base_typedie, base_size, locp, 0);
      if (used < 0 || used > 8)
	return used;
      if (size % (*locp)[1].number != 0)
	return 0;
      fpregs_used += used * (size / (*locp)[1].number);
      break;

    default:
      return 9;
    }

  return fpregs_used;
}
Ejemplo n.º 28
0
/** \brief Populate the list of members of a type
 *
 *  \param info ELF object containing the type DIE
 *  \param die  DIE of the type
 *  \param unit DIE of the compilation unit containing the type DIE
 *  \param type the type
 */
static void MC_dwarf_add_members(simgrid::mc::ObjectInformation* info, Dwarf_Die * die,
                                 Dwarf_Die * unit, simgrid::mc::Type* type)
{
  int res;
  Dwarf_Die child;
  xbt_assert(type->members.empty());
  for (res = dwarf_child(die, &child); res == 0;
       res = dwarf_siblingof(&child, &child)) {
    int tag = dwarf_tag(&child);
    if (tag == DW_TAG_member || tag == DW_TAG_inheritance) {

      // Skip declarations:
      if (MC_dwarf_attr_flag(&child, DW_AT_declaration, false))
        continue;

      // Skip compile time constants:
      if (dwarf_hasattr(&child, DW_AT_const_value))
        continue;

      // TODO, we should use another type (because is is not a type but a member)
      simgrid::mc::Member member;
      if (tag == DW_TAG_inheritance)
        member.flags |= simgrid::mc::Member::INHERITANCE_FLAG;

      const char *name = MC_dwarf_attr_integrate_string(&child, DW_AT_name);
      if (name)
        member.name = name;
      // Those base names are used by GCC and clang for virtual table pointers
      // respectively ("__vptr$ClassName", "__vptr.ClassName"):
      if (boost::algorithm::starts_with(member.name, "__vptr$") ||
        boost::algorithm::starts_with(member.name, "__vptr."))
        member.flags |= simgrid::mc::Member::VIRTUAL_POINTER_FLAG;
      // A cleaner solution would be to check against the type:
      // ---
      // tag: DW_TAG_member
      // name: "_vptr$Foo"
      // type:
      //   # Type for a pointer to a vtable
      //   tag: DW_TAG_pointer_type
      //   type:
      //     # Type for a vtable:
      //     tag: DW_TAG_pointer_type
      //     name: "__vtbl_ptr_type"
      //     type:
      //       tag: DW_TAG_subroutine_type
      //       type:
      //         tag: DW_TAG_base_type
      //         name: "int"
      // ---

      member.byte_size =
          MC_dwarf_attr_integrate_uint(&child, DW_AT_byte_size, 0);
      member.type_id = MC_dwarf_at_type(&child);

      if (dwarf_hasattr(&child, DW_AT_data_bit_offset))
        xbt_die("Can't groke DW_AT_data_bit_offset.");

      MC_dwarf_fill_member_location(type, &member, &child);

      if (not member.type_id)
        xbt_die("Missing type for member %s of <%" PRIx64 ">%s",
                member.name.c_str(),
                (uint64_t) type->id, type->name.c_str());

      type->members.push_back(std::move(member));
    }
  }
}
Ejemplo n.º 29
0
Archivo: types.c Proyecto: adk9/ohm
int
add_complextype_from_die(Dwarf_Debug dbg, Dwarf_Die parent_die, Dwarf_Die die)
{
    int ret = DW_DLV_ERROR, i, nsib;
    Dwarf_Error err = 0;
    Dwarf_Off offset = 0;
    Dwarf_Half tag = 0;
    Dwarf_Attribute attr;
    Dwarf_Unsigned bsz = 0, tid = 0;
    Dwarf_Die grandchild;
    basetype_t *t, *t2;

    ret = dwarf_tag(die, &tag, &err);
    if (ret != DW_DLV_OK) {
        derror("error in dwarf_tag()");
        goto error;
    }

    if ((tag != DW_TAG_array_type) && (tag != DW_TAG_structure_type) &&
        (tag != DW_TAG_typedef) && (tag != DW_TAG_pointer_type))
        return -1;

    switch (tag) {
        case DW_TAG_array_type:
            ret = get_offset_tid(die, &offset, &tid);
            if (ret < 0) {
                derror("error in get_offset_tid()");
                goto error;
            }

            // get the child
            dwarf_child(die, &grandchild, &err);
            ret = dwarf_attr(grandchild, DW_AT_upper_bound, &attr, &err);
            if (ret == DW_DLV_ERROR) {
                derror("error in dwarf_attr(DW_AT_upper_bound)");
                goto error;
            } else if (ret == DW_DLV_OK)
                get_number(attr, &bsz);
            else
                return 0;

            t = get_or_add_type(offset);
            snprintf(t->name, 128, "arr%u[]", (unsigned int)offset);
            t->ohm_type = OHM_TYPE_ARRAY;
            t->nelem = bsz+1;
            t2 = get_or_add_type(tid);
            t->size = t->nelem * get_type_size(t2);
            t->elems = malloc(sizeof(t));
            t->elems[0] = t2;
            break;

        case DW_TAG_structure_type:
            ret = dwarf_die_CU_offset(die, &offset, &err);
            if (ret != DW_DLV_OK) {
                derror("error in dwarf_die_CU_offset()");
                goto error;
            }

            t = get_or_add_type(offset);
            strncpy(t->name, "struct ", 7);
            ret = get_child_name(dbg, die, t->name+7, 128);
            if (ret < 0)
                strncpy(t->name, "<unknown-struct>", 128);
            t->ohm_type = OHM_TYPE_STRUCT;
            ret = dwarf_bytesize(die, &bsz, &err);
            t->size = ((ret == DW_DLV_OK) ? bsz : 0);

            // ensure that struct members get added to the table
            nsib = traverse_die(&add_structmember_from_die, dbg, parent_die, die);
            if (nsib < 0)
                goto error;
            t->nelem = nsib;
            t->elems = malloc((t->nelem)*sizeof(t));
            for (i = 0; i < t->nelem; i++)
                t->elems[i] = &types_table[types_table_size-t->nelem-1+i];
            break;

        case DW_TAG_typedef:
            ret = get_offset_tid(die, &offset, &tid);
            if (ret < 0) {
                derror("error in get_offset_tid()");
                goto error;
            }

            t = get_or_add_type(offset);
            t->ohm_type = OHM_TYPE_ALIAS;
            t->size = 0;
            t->nelem = 1;
            t2 = get_or_add_type(tid);
            t->elems = malloc(sizeof(t));
            t->elems[0] = t2;
            ret = get_child_name(dbg, die, t->name, 128);
            if (ret < 0)
                strncpy(t->name, "<unknown-typedef>", 128);
            break;

        case DW_TAG_pointer_type:
            ret = get_offset_tid(die, &offset, &tid);
            if (ret < 0) {
                derror("error in get_offset_tid()");
                goto error;
            }

            t = get_or_add_type(offset);
            strncpy(t->name, "ptr", 128);
            t->ohm_type = OHM_TYPE_PTR;
            t->nelem = 1;
            t->size = sizeof(void*);
            t2 = get_type(tid);
            t->size = get_type_size(t2);
            t->elems = malloc(sizeof(t));
            t->elems[0] = t2;
            break;
            
        default:
            break;
    }

    return 1;

error:
    derror("error in add_complextype_from_die()");
    return -1;
}
Ejemplo n.º 30
0
int
main (int argc, char *argv[])
{
  for (int i = 1; i < argc; ++i)
    {
      int fd = open (argv[i], O_RDONLY);

      Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
      if (dbg != NULL)
	{
	  Dwarf_Off off = 0;
	  size_t cuhl;
	  Dwarf_Off noff;

	  while (dwarf_nextcu (dbg, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
	    {
	      Dwarf_Die die_mem;
	      Dwarf_Die *die = dwarf_offdie (dbg, off + cuhl, &die_mem);

	      Dwarf_Die iter_mem;
	      Dwarf_Die *iter = &iter_mem;
	      dwarf_child (die, &iter_mem);

	      while (1)
		{
		  if (dwarf_tag (iter) == DW_TAG_variable)
		    {
		      Dwarf_Attribute attr_mem;
		      Dwarf_Die form_mem;
		      dwarf_formref_die (dwarf_attr (iter, DW_AT_type,
						     &attr_mem),
					 &form_mem);
		    }

		  if (dwarf_siblingof (iter, &iter_mem) != 0)
		    break;
		}

	      off = noff;
	    }

	  off = 0;
	  uint64_t type_sig;

	  while (dwarf_next_unit (dbg, off, &noff, &cuhl, NULL, NULL, NULL,
				  NULL, &type_sig, NULL) == 0)
	    {
	      Dwarf_Die die_mem;
	      Dwarf_Die *die = dwarf_offdie_types (dbg, off + cuhl, &die_mem);

	      if (die == NULL)
		printf ("fail\n");
	      else
		printf ("ok\n");

	      off = noff;
	    }

	  dwarf_end (dbg);
	}

      close (fd);
    }
}