static void
print_comp_dir(Dwarf_Debug dbg,Dwarf_Die die,int level, struct srcfilesdata *sf)
{
    int res;
    Dwarf_Error error = 0;
    Dwarf_Attribute *attrbuf = 0;
    Dwarf_Signed attrcount = 0;
    Dwarf_Unsigned i;
    res = dwarf_attrlist(die,&attrbuf,&attrcount,&error);
    if(res != DW_DLV_OK) {
        return;
    }
    sf->srcfilesres = dwarf_srcfiles(die,&sf->srcfiles,&sf->srcfilescount, 
        &error);
    for(i = 0; i < attrcount ; ++i) {
        Dwarf_Half aform;
        res = dwarf_whatattr(attrbuf[i],&aform,&error);
        if(res == DW_DLV_OK) {
            if(aform == DW_AT_comp_dir) {
                char *name = 0;
                res = dwarf_formstring(attrbuf[i],&name,&error);
                if(res == DW_DLV_OK) {
                    printf(    "<%3d> compilation directory : \"%s\"\n",
                        level,name);
                }
            }
            if(aform == DW_AT_stmt_list) {
                /* Offset of stmt list for this CU in .debug_line */
            }
        }
        dwarf_dealloc(dbg,attrbuf[i],DW_DLA_ATTR);
    }
    dwarf_dealloc(dbg,attrbuf,DW_DLA_LIST);
}
Dwarf_Loc dwarf_get_variable_location(Dwarf_Die die, struct dwarf_compilation_unit * unit){
  
  Dwarf_Error error = 0;
  Dwarf_Attribute *attrbuf = 0;
  Dwarf_Signed attrcount = 0;
  Dwarf_Unsigned i;
  Dwarf_Locdesc *llbuf = 0;
  Dwarf_Locdesc **llbufarray = 0;
  Dwarf_Signed no_of_elements;
  int lres = 0;
  Dwarf_Loc first_loc;

  int res = dwarf_attrlist(die,&attrbuf,&attrcount,&error);
  if(res != DW_DLV_OK) {
    return first_loc;
  }
  for(i = 0; i < attrcount ; ++i) {
    Dwarf_Half aform;
    res = dwarf_whatattr(attrbuf[i],&aform,&error);
    if(aform == DW_AT_location) {
      lres = dwarf_loclist_n(attrbuf[i], &llbufarray, &no_of_elements, &error);
      if (llbufarray[0]->ld_s){
        first_loc = (llbufarray[0]->ld_s)[0];
	return first_loc;
      }
    }
  }
  return first_loc;
}
Exemplo n.º 3
0
QVector< Dwarf_Half > DwarfDie::attributes() const
{
    Dwarf_Attribute* attrList;
    Dwarf_Signed attrCount;
    auto res = dwarf_attrlist(m_die, &attrList, &attrCount, nullptr);
    if (res != DW_DLV_OK)
        return {};

    QVector<Dwarf_Half> attrs;
    attrs.reserve(attrCount);
    for (int i = 0; i < attrCount; ++i) {
        Dwarf_Half attrType;
        res = dwarf_whatattr(attrList[i], &attrType, nullptr);
        if (res != DW_DLV_OK)
            continue;
        attrs.push_back(attrType);
    }

    dwarf_dealloc(dwarfHandle(), attrList, DW_DLA_LIST);

    if (const auto die = inheritedFrom()) {
        auto inheritedAttrs = die->attributes();
        // remove attributes that must not be inherited
        inheritedAttrs.erase(
            std::remove_if(inheritedAttrs.begin(), inheritedAttrs.end(), [](Dwarf_Half at) {
                return at == DW_AT_declaration || at == DW_AT_sibling;
            }), inheritedAttrs.end());

        attrs += inheritedAttrs;
        std::sort(attrs.begin(), attrs.end());
        attrs.erase(std::unique(attrs.begin(), attrs.end()), attrs.end());
    }

    return attrs;
}
static void
print_subprog(Dwarf_Debug dbg,Dwarf_Die die, int level,
    struct srcfilesdata *sf)
{
    int res;
    Dwarf_Error error = 0;
    Dwarf_Attribute *attrbuf = 0;
    Dwarf_Addr lowpc = 0;
    Dwarf_Addr highpc = 0;
    Dwarf_Signed attrcount = 0;
    Dwarf_Unsigned i;
    Dwarf_Unsigned filenum = 0;
    Dwarf_Unsigned linenum = 0;
    char *filename = 0;
    res = dwarf_attrlist(die,&attrbuf,&attrcount,&error);
    if(res != DW_DLV_OK) {
        return;
    }
    for(i = 0; i < attrcount ; ++i) {
        Dwarf_Half aform;
        res = dwarf_whatattr(attrbuf[i],&aform,&error);
        if(res == DW_DLV_OK) {
            if(aform == DW_AT_decl_file) {
                get_number(attrbuf[i],&filenum);
                if((filenum > 0) && (sf->srcfilescount > (filenum-1))) {
                    filename = sf->srcfiles[filenum-1];
                }
            }
            if(aform == DW_AT_decl_line) {
                get_number(attrbuf[i],&linenum);
            }
            if(aform == DW_AT_low_pc) {
                get_addr(attrbuf[i],&lowpc);
            }
            if(aform == DW_AT_high_pc) {
                get_addr(attrbuf[i],&highpc);
            }
        }
        dwarf_dealloc(dbg,attrbuf[i],DW_DLA_ATTR);
    }
    if(filenum || linenum) {
        printf("<%3d> file: %" DW_PR_DUu " %s  line %"
            DW_PR_DUu "\n",level,filenum,filename?filename:"",linenum);
    }
    if(lowpc) {
        printf("<%3d> low_pc : 0x%" DW_PR_DUx  "\n",
            level, (Dwarf_Unsigned)lowpc);
    }
    if(highpc) {
        printf("<%3d> high_pc: 0x%" DW_PR_DUx  "\n",
            level, (Dwarf_Unsigned)highpc);
    }
    dwarf_dealloc(dbg,attrbuf,DW_DLA_LIST);
}
Exemplo n.º 5
0
static int
get_attributes(Dwarf_Debug dbg,Dwarf_Die die, int level,
    struct srcfilesdata *sf, struct attributes *attr)
{
    int res;
    Dwarf_Error error = 0;
    Dwarf_Attribute *attrbuf = 0;
    Dwarf_Addr lowpc = 0;
    Dwarf_Addr highpc = 0;
    Dwarf_Signed attrcount = 0;
    Dwarf_Unsigned i;
    Dwarf_Unsigned filenum = 0;
    Dwarf_Unsigned linenum = 0;
    char *filename = 0;
    int ret = 1;
    res = dwarf_attrlist(die,&attrbuf,&attrcount,&error);
    if(res != DW_DLV_OK) {
        return ret;
    }
    for(i = 0; i < attrcount ; ++i) {
        Dwarf_Half aform;
        res = dwarf_whatattr(attrbuf[i],&aform,&error);
        if(res == DW_DLV_OK) {
            if(aform == DW_AT_decl_file) {
                get_number(attrbuf[i],&filenum);
                if((filenum > 0) && (sf->srcfilescount > (filenum-1))) {
                    filename = sf->srcfiles[filenum-1];
                    attr->filename = filename;
                }
            }
            if(aform == DW_AT_declaration) {
             	Dwarf_Unsigned size=0;
                 get_number(attrbuf[i],&size);
                 ret =0;
             }
            if(aform == DW_AT_byte_size) {
            	attr->size=0;
                get_number(attrbuf[i],&attr->size);
            }
            if(aform == DW_AT_data_member_location) {
            	attr->member_location=0;
                get_number(attrbuf[i],&attr->member_location);
            }
            if(aform == DW_AT_type) {
            	attr->type_offset = 0;
            	dwarf_global_formref(attrbuf[i],&(attr->type_offset),&error);
            }
        }
        dwarf_dealloc(dbg,attrbuf[i],DW_DLA_ATTR);
    }

    dwarf_dealloc(dbg,attrbuf,DW_DLA_LIST);
    return ret;
}
Exemplo n.º 6
0
/* List a function if it's in the given DIE.
*/
void list_func_in_die(Dwarf_Debug dgb, Dwarf_Die the_die, FILE *fp)
{
    char* die_name = 0;
    const char* tag_name = 0;
    Dwarf_Error err;
    Dwarf_Half tag;
    Dwarf_Attribute* attrs;
    Dwarf_Addr lowpc, highpc;
    Dwarf_Signed attrcount, i;
    int rc = dwarf_diename(the_die, &die_name, &err);

    if (rc == DW_DLV_ERROR)
        die("Error in dwarf_diename\n");
    else if (rc == DW_DLV_NO_ENTRY)
        return;

    if (dwarf_tag(the_die, &tag, &err) != DW_DLV_OK)
        die("Error in dwarf_tag\n");

    /* Only interested in subprogram DIEs here */
    if (tag != DW_TAG_subprogram)
        return;

    if (dwarf_get_TAG_name(tag, &tag_name) != DW_DLV_OK)
        die("Error in dwarf_get_TAG_name\n");

    //printf("DW_TAG_subprogram: '%s'\n", die_name);
    fprintf(fp, "%s\t", die_name);
    

    /* Grab the DIEs attributes for display */
    if (dwarf_attrlist(the_die, &attrs, &attrcount, &err) != DW_DLV_OK)
        die("Error in dwarf_attlist\n");

    for (i = 0; i < attrcount; ++i) {
        Dwarf_Half attrcode;
        if (dwarf_whatattr(attrs[i], &attrcode, &err) != DW_DLV_OK)
            die("Error in dwarf_whatattr\n");

        /* We only take some of the attributes for display here.
        ** More can be picked with appropriate tag constants.
        */
        if (attrcode == DW_AT_low_pc)
            dwarf_formaddr(attrs[i], &lowpc, 0);
        else if (attrcode == DW_AT_high_pc)
            dwarf_formaddr(attrs[i], &highpc, 0);
    }

    fprintf(fp, "%08llx\n", lowpc);
//    printf("low pc  : 0x%08llx\n", lowpc);
//    printf("high pc : 0x%08llx\n", highpc);
}
Exemplo n.º 7
0
//print_cmd helper funcs
error_t ip_in_func(Dwarf_Die the_die, size_t rip, bool* res){
	char* die_name = 0;
	Dwarf_Error err;
	Dwarf_Half tag;
	Dwarf_Attribute* attrs;
	Dwarf_Addr lowpc, highpc;
	Dwarf_Signed attrcount, i;
	int rc = dwarf_diename(the_die, &die_name, &err);

	if (rc == DW_DLV_ERROR)
		return E_FATAL;
	else if (rc == DW_DLV_NO_ENTRY)
		return E_NONE;

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

	/* Only interested in subprogram DIEs here */
	if (tag != DW_TAG_subprogram)
		return E_NONE;

	/* Grab the DIEs attributes for display */
	if (dwarf_attrlist(the_die, &attrs, &attrcount, &err) != DW_DLV_OK)
		return E_FATAL;
	
	for (i = 0; i < attrcount; ++i) {
		Dwarf_Half attrcode;
		if (dwarf_whatattr(attrs[i], &attrcode, &err) != DW_DLV_OK)
			return E_FATAL;

		/* We only take some of the attributes for display here.
		** More can be picked with appropriate tag constants.
		*/
		if (attrcode == DW_AT_low_pc)
			dwarf_formaddr(attrs[i], &lowpc, 0);
		else if (attrcode == DW_AT_high_pc)
			dwarf_formaddr(attrs[i], &highpc, 0);
		
	}

	if( rip >= lowpc && rip <= highpc){
			*res = true;
			return E_NONE;
		}
	

	return E_NONE;

}
Exemplo n.º 8
0
error_t is_right_var(Dwarf_Die var_die, char* var_name, bool* found){
	char* die_name = 0;
	Dwarf_Error err;
	Dwarf_Half tag;
	Dwarf_Attribute* attrs;
	Dwarf_Signed attrcount, i;
	int rc = dwarf_diename(var_die, &die_name, &err);

	if (rc == DW_DLV_ERROR)
		return E_FATAL;
	else if (rc == DW_DLV_NO_ENTRY)
		return E_NONE;

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

	/* Only interested in variable DIEs here */
	if (tag != DW_TAG_variable)
		return E_NONE;


	/* Grab the DIEs attributes for display */
	if (dwarf_attrlist(var_die, &attrs, &attrcount, &err) != DW_DLV_OK)
		return E_FATAL;
	
	for (i = 0; i < attrcount; ++i) {
		Dwarf_Half attrcode;
		if (dwarf_whatattr(attrs[i], &attrcode, &err) != DW_DLV_OK)
			return E_FATAL;

		
		if (attrcode == DW_AT_name){
			char* die_var_name;
			dwarf_formstring(attrs[i], &die_var_name, &err);
			if( strcmp(die_var_name, var_name) == 0 ){
				*found = true;
				return E_NONE;	
			}
		}		
		
	}

	return E_NONE; //Not var_die being searched for
}
Exemplo n.º 9
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);
}
unsigned long dwarf_function_ending_address(Dwarf_Die function_die,  struct dwarf_compilation_unit * unit){
  Dwarf_Error error = 0;
  Dwarf_Attribute *attrbuf = 0;
  Dwarf_Addr highpc = 0;
  Dwarf_Signed attrcount = 0;
  Dwarf_Unsigned i;

  int res = dwarf_attrlist(function_die,&attrbuf,&attrcount,&error);
  if(res != DW_DLV_OK) {
    return 0;
  }
  for(i = 0; i < attrcount ; ++i) {
    Dwarf_Half aform;
    res = dwarf_whatattr(attrbuf[i],&aform,&error);
    if(aform == DW_AT_high_pc) {
      get_addr(attrbuf[i],&highpc);
      return highpc;
    }
  }
  return 0;
}
char * dwarf_get_name(Dwarf_Die function_die,  struct dwarf_compilation_unit * unit){
  Dwarf_Error error = 0;
  Dwarf_Attribute *attrbuf = 0;
  Dwarf_Addr highpc = 0;
  Dwarf_Signed attrcount = 0;
  Dwarf_Unsigned i;

  int res = dwarf_attrlist(function_die,&attrbuf,&attrcount,&error);
  if(res != DW_DLV_OK) {
    return 0;
  }
  for(i = 0; i < attrcount ; ++i) {
    Dwarf_Half aform;
    res = dwarf_whatattr(attrbuf[i],&aform,&error);
    if (aform == DW_AT_name) {
      char * tmpName;
      res = dwarf_formstring(attrbuf[i], &tmpName, &error);
      return tmpName;
    }
  }
  return NULL;
}
Exemplo n.º 12
0
Arquivo: rdwarf.c Projeto: kubo/rdwarf
static VALUE rd_attr_new(rd_shared_data_t *sd, VALUE top, VALUE cu, Dwarf_Attribute attr)
{
    rd_attr_t *rd_attr;
    Dwarf_Error err;
    VALUE obj;
    VALUE klass;
    Dwarf_Half attr_type = 0;

    chkerr1(dwarf_whatattr(attr, &attr_type, &err), &err, Qnil);
    klass = rb_hash_aref(rdwarf_at2class, INT2FIX(attr_type));
    if (NIL_P(klass)) {
        rb_raise(rb_eRuntimeError, "unknown attribute %d\n", attr_type);
    }
    obj = rd_attr_s_alloc(klass);
    rd_attr = GetAttr(obj);
    rd_attr->shared_data = rd_shared_data_ref(sd);
    rd_attr->attr = attr;
    rd_attr->attr_type = attr_type;
    rb_ivar_set(obj, id_at_top, top);
    rb_ivar_set(obj, id_at_cu, cu);
    return obj;
}
void
handle (Dwarf *dbg, Dwarf_Die *die, int n)
{
  Dwarf_Die child;
  unsigned int tag;
  const char *str;
  char buf[30];
  const char *name;
  Dwarf_Off off;
  Dwarf_Off cuoff;
  size_t cnt;
  Dwarf_Addr addr;
  int i;

  tag = dwarf_tag (die);
  if (tag != DW_TAG_invalid)
    {
      if (tag < ntagnames)
	str = tagnames[tag];
      else
	{
	  snprintf (buf, sizeof buf, "%#x", tag);
	  str = buf;
	}
    }
  else
    str = "* NO TAG *";

  name = dwarf_diename (die);
  if (name == 0)
    name = "* NO NAME *";

  off = dwarf_dieoffset (die);
  cuoff = dwarf_cuoffset (die);

  printf ("%*s%s\n", n * 5, "", str);
  printf ("%*s Name      : %s\n", n * 5, "", name);
  printf ("%*s Offset    : %lld\n", n * 5, "", (long long int) off);
  printf ("%*s CU offset : %lld\n", n * 5, "", (long long int) cuoff);

  printf ("%*s Attrs     :", n * 5, "");
  for (cnt = 0; cnt < nattrs; ++cnt)
    if (dwarf_hasattr (die, attrs[cnt].code))
      printf (" %s", attrs[cnt].name);
  puts ("");

  if (dwarf_hasattr (die, DW_AT_low_pc) && dwarf_lowpc (die, &addr) == 0)
    {
      Dwarf_Attribute attr;
      Dwarf_Addr addr2;
      printf ("%*s low PC    : %#llx\n",
	      n * 5, "", (unsigned long long int) addr);

      if (dwarf_attr (die, DW_AT_low_pc, &attr) == NULL
	  || dwarf_formaddr (&attr, &addr2) != 0
	  || addr != addr2)
	puts ("************* DW_AT_low_pc verify failed ************");
      else if (! dwarf_hasform (&attr, DW_FORM_addr))
	puts ("************* DW_AT_low_pc form failed ************");
      else if (dwarf_whatform (&attr) != DW_FORM_addr)
	puts ("************* DW_AT_low_pc form (2) failed ************");
      else if (dwarf_whatattr (&attr) != DW_AT_low_pc)
	puts ("************* DW_AT_low_pc attr failed ************");
    }
  if (dwarf_hasattr (die, DW_AT_high_pc) && dwarf_highpc (die, &addr) == 0)
    {
      Dwarf_Attribute attr;
      Dwarf_Addr addr2;
      printf ("%*s high PC   : %#llx\n",
	      n * 5, "", (unsigned long long int) addr);
      if (dwarf_attr (die, DW_AT_high_pc, &attr) == NULL
	  || dwarf_formaddr (&attr, &addr2) != 0
	  || addr != addr2)
	puts ("************* DW_AT_high_pc verify failed ************");
      else if (! dwarf_hasform (&attr, DW_FORM_addr))
	puts ("************* DW_AT_high_pc form failed ************");
      else if (dwarf_whatform (&attr) != DW_FORM_addr)
	puts ("************* DW_AT_high_pc form (2) failed ************");
      else if (dwarf_whatattr (&attr) != DW_AT_high_pc)
	puts ("************* DW_AT_high_pc attr failed ************");
    }

  if (dwarf_hasattr (die, DW_AT_byte_size) && (i = dwarf_bytesize (die)) != -1)
    {
      Dwarf_Attribute attr;
      Dwarf_Word u2;
      unsigned int u;
      printf ("%*s byte size : %d\n", n * 5, "", i);
      if (dwarf_attr (die, DW_AT_byte_size, &attr) == NULL
	  || dwarf_formudata (&attr, &u2) != 0
	  || i != (int) u2)
	puts ("************* DW_AT_byte_size verify failed ************");
      else if (! dwarf_hasform (&attr, DW_FORM_data1)
	       && ! dwarf_hasform (&attr, DW_FORM_data2)
	       && ! dwarf_hasform (&attr, DW_FORM_data4)
	       && ! dwarf_hasform (&attr, DW_FORM_data8)
	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
	       && ! dwarf_hasform (&attr, DW_FORM_udata))
	puts ("************* DW_AT_byte_size form failed ************");
      else if ((u = dwarf_whatform (&attr)) == 0
	       || (u != DW_FORM_data1
		   && u != DW_FORM_data2
		   && u != DW_FORM_data4
		   && u != DW_FORM_data8
		   && u != DW_FORM_sdata
		   && u != DW_FORM_udata))
	puts ("************* DW_AT_byte_size form (2) failed ************");
      else if (dwarf_whatattr (&attr) != DW_AT_byte_size)
	puts ("************* DW_AT_byte_size attr failed ************");
    }
  if (dwarf_hasattr (die, DW_AT_bit_size) && (i = dwarf_bitsize (die)) != -1)
    {
      Dwarf_Attribute attr;
      Dwarf_Word u2;
      unsigned int u;
      printf ("%*s bit size  : %d\n", n * 5, "", i);
      if (dwarf_attr (die, DW_AT_bit_size, &attr) == NULL
	  || dwarf_formudata (&attr, &u2) != 0
	  || i != (int) u2)
	puts ("************* DW_AT_bit_size test failed ************");
      else if (! dwarf_hasform (&attr, DW_FORM_data1)
	       && ! dwarf_hasform (&attr, DW_FORM_data2)
	       && ! dwarf_hasform (&attr, DW_FORM_data4)
	       && ! dwarf_hasform (&attr, DW_FORM_data8)
	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
	       && ! dwarf_hasform (&attr, DW_FORM_udata))
	puts ("************* DW_AT_bit_size form failed ************");
      else if ((u = dwarf_whatform (&attr)) == 0
	       || (u != DW_FORM_data1
		   && u != DW_FORM_data2
		   && u != DW_FORM_data4
		   && u != DW_FORM_data8
		   && u != DW_FORM_sdata
		   && u != DW_FORM_udata))
	puts ("************* DW_AT_bit_size form (2) failed ************");
      else if (dwarf_whatattr (&attr) != DW_AT_bit_size)
	puts ("************* DW_AT_bit_size attr failed ************");
    }
  if (dwarf_hasattr (die, DW_AT_bit_offset)
      && (i = dwarf_bitoffset (die)) != -1)
    {
      Dwarf_Attribute attr;
      Dwarf_Word u2;
      unsigned int u;
      printf ("%*s bit offset: %d\n", n * 5, "", i);
      if (dwarf_attr (die, DW_AT_bit_offset, &attr) == NULL
	  || dwarf_formudata (&attr, &u2) != 0
	  || i != (int) u2)
	puts ("************* DW_AT_bit_offset test failed ************");
      else if (! dwarf_hasform (&attr, DW_FORM_data1)
	       && ! dwarf_hasform (&attr, DW_FORM_data2)
	       && ! dwarf_hasform (&attr, DW_FORM_data4)
	       && ! dwarf_hasform (&attr, DW_FORM_data8)
	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
	       && ! dwarf_hasform (&attr, DW_FORM_udata))
	puts ("************* DW_AT_bit_offset form failed ************");
      else if ((u = dwarf_whatform (&attr)) == 0
	       || (u != DW_FORM_data1
		   && u != DW_FORM_data2
		   && u != DW_FORM_data4
		   && u != DW_FORM_data8
		   && u != DW_FORM_sdata
		   && u != DW_FORM_udata))
	puts ("************* DW_AT_bit_offset form (2) failed ************");
      else if (dwarf_whatattr (&attr) != DW_AT_bit_offset)
	puts ("************* DW_AT_bit_offset attr failed ************");
    }

  if (dwarf_hasattr (die, DW_AT_language) && (i = dwarf_srclang (die)) != -1)
    {
      Dwarf_Attribute attr;
      Dwarf_Word u2;
      unsigned int u;
      printf ("%*s language  : %d\n", n * 5, "", i);
      if (dwarf_attr (die, DW_AT_language, &attr) == NULL
	  || dwarf_formudata (&attr, &u2) != 0
	  || i != (int) u2)
	puts ("************* DW_AT_language test failed ************");
      else if (! dwarf_hasform (&attr, DW_FORM_data1)
	       && ! dwarf_hasform (&attr, DW_FORM_data2)
	       && ! dwarf_hasform (&attr, DW_FORM_data4)
	       && ! dwarf_hasform (&attr, DW_FORM_data8)
	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
	       && ! dwarf_hasform (&attr, DW_FORM_udata))
	puts ("************* DW_AT_language form failed ************");
      else if ((u = dwarf_whatform (&attr)) == 0
	       || (u != DW_FORM_data1
		   && u != DW_FORM_data2
		   && u != DW_FORM_data4
		   && u != DW_FORM_data8
		   && u != DW_FORM_sdata
		   && u != DW_FORM_udata))
	puts ("************* DW_AT_language form (2) failed ************");
      else if (dwarf_whatattr (&attr) != DW_AT_language)
	puts ("************* DW_AT_language attr failed ************");
    }

  if (dwarf_hasattr (die, DW_AT_ordering)
      && (i = dwarf_arrayorder (die)) != -1)
    {
      Dwarf_Attribute attr;
      Dwarf_Word u2;
      unsigned int u;
      printf ("%*s ordering  : %d\n", n * 5, "", i);
      if (dwarf_attr (die, DW_AT_ordering, &attr) == NULL
	  || dwarf_formudata (&attr, &u2) != 0
	  || i != (int) u2)
	puts ("************* DW_AT_ordering test failed ************");
      else if (! dwarf_hasform (&attr, DW_FORM_data1)
	       && ! dwarf_hasform (&attr, DW_FORM_data2)
	       && ! dwarf_hasform (&attr, DW_FORM_data4)
	       && ! dwarf_hasform (&attr, DW_FORM_data8)
	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
	       && ! dwarf_hasform (&attr, DW_FORM_udata))
	puts ("************* DW_AT_ordering failed ************");
      else if ((u = dwarf_whatform (&attr)) == 0
	       || (u != DW_FORM_data1
		   && u != DW_FORM_data2
		   && u != DW_FORM_data4
		   && u != DW_FORM_data8
		   && u != DW_FORM_sdata
		   && u != DW_FORM_udata))
	puts ("************* DW_AT_ordering form (2) failed ************");
      else if (dwarf_whatattr (&attr) != DW_AT_ordering)
	puts ("************* DW_AT_ordering attr failed ************");
    }

  if (dwarf_hasattr (die, DW_AT_comp_dir))
    {
      Dwarf_Attribute attr;
      if (dwarf_attr (die, DW_AT_comp_dir, &attr) == NULL
	  || (name = dwarf_formstring (&attr)) == NULL)
	puts ("************* DW_AT_comp_dir attr failed ************");
      else
	printf ("%*s directory : %s\n", n * 5, "", name);
    }

  if (dwarf_hasattr (die, DW_AT_producer))
    {
      Dwarf_Attribute attr;
      if (dwarf_attr (die, DW_AT_producer, &attr) == NULL
	  || (name = dwarf_formstring (&attr)) == NULL)
	puts ("************* DW_AT_comp_dir attr failed ************");
      else
	printf ("%*s producer  : %s\n", n * 5, "", name);
    }

  if (dwarf_haschildren (die) != 0 && dwarf_child (die, &child) == 0)
    handle (dbg, &child, n + 1);
  if (dwarf_siblingof (die, die) == 0)
    handle (dbg, die, n);
}
Exemplo n.º 14
0
static void
print_expr (Dwarf_Attribute *attr, Dwarf_Op *expr, Dwarf_Addr addr)
{
  uint8_t atom = expr->atom;
  const char *opname = dwarf_opcode_string (atom);
  assert (opname != NULL);

  switch (atom)
    {
    case DW_OP_deref:
    case DW_OP_dup:
    case DW_OP_drop:
    case DW_OP_over:
    case DW_OP_swap:
    case DW_OP_rot:
    case DW_OP_xderef:
    case DW_OP_abs:
    case DW_OP_and:
    case DW_OP_div:
    case DW_OP_minus:
    case DW_OP_mod:
    case DW_OP_mul:
    case DW_OP_neg:
    case DW_OP_not:
    case DW_OP_or:
    case DW_OP_plus:
    case DW_OP_shl:
    case DW_OP_shr:
    case DW_OP_shra:
    case DW_OP_xor:
    case DW_OP_eq:
    case DW_OP_ge:
    case DW_OP_gt:
    case DW_OP_le:
    case DW_OP_lt:
    case DW_OP_ne:
    case DW_OP_lit0 ... DW_OP_lit31:
    case DW_OP_reg0 ... DW_OP_reg31:
    case DW_OP_nop:
    case DW_OP_stack_value:
      /* No arguments. */
      printf ("%s", opname);
      break;

    case DW_OP_form_tls_address:
      /* No arguments. Special. Pops an address and pushes the
	 corresponding address in the current thread local
	 storage. Uses the thread local storage block of the defining
	 module (executable, shared library). */
      printf ("%s", opname);
      break;

    case DW_OP_GNU_push_tls_address:
      /* No arguments. Special. Not the same as DW_OP_form_tls_address.
	 Pops an offset into the current thread local strorage and
	 pushes back the actual address. */
      printf ("%s", opname);
      break;

    case DW_OP_call_frame_cfa:
      /* No arguments. Special. Pushes Call Frame Address as computed
	 by CFI data (dwarf_cfi_addrframe will fetch that info (either from
	 the .eh_frame or .debug_frame CFI) and dwarf_frame_cfa translatesr
         the CFI instructions into a plain DWARF expression.
	 Never used in CFI itself. */

      if (attr == NULL)
	error (EXIT_FAILURE, 0, "%s used in CFI", opname);

      printf ("%s ", opname);
      if (cfi_eh == NULL && cfi_debug == NULL)
	error (EXIT_FAILURE, 0, "DW_OP_call_frame_cfa used but no cfi found.");

      Dwarf_Frame *frame;
      if (dwarf_cfi_addrframe (cfi_eh, addr + cfi_eh_bias, &frame) != 0
	  && dwarf_cfi_addrframe (cfi_debug, addr, &frame) != 0)
	error (EXIT_FAILURE, 0, "dwarf_cfi_addrframe 0x%" PRIx64 ": %s",
	       addr, dwarf_errmsg (-1));

      Dwarf_Op *cfa_ops;
      size_t cfa_nops;
      if (dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops) != 0)
	error (EXIT_FAILURE, 0, "dwarf_frame_cfa 0x%" PRIx64 ": %s",
	       addr, dwarf_errmsg (-1));
      if (cfa_nops < 1)
	error (EXIT_FAILURE, 0, "dwarf_frame_cfa no ops");
      print_expr_block (NULL, cfa_ops, cfa_nops, 0);
      free (frame);
      break;

    case DW_OP_push_object_address:
      /* No arguments. Special. Pushes object address explicitly.
       Normally only done implicitly by DW_AT_data_member_location.
       Never used in CFI. */
      if (attr == NULL)
	error (EXIT_FAILURE, 0, "%s used in CFI", opname);
      printf ("%s", opname);
      break;

    case DW_OP_addr:
      /* 1 address argument. */
      printf ("%s(0x%" PRIx64 ")", opname, (Dwarf_Addr) expr->number);
      break;

    case DW_OP_const1u:
    case DW_OP_const2u:
    case DW_OP_const4u:
    case DW_OP_const8u:
    case DW_OP_constu:
    case DW_OP_pick:
    case DW_OP_plus_uconst:
    case DW_OP_regx:
    case DW_OP_piece:
    case DW_OP_deref_size:
    case DW_OP_xderef_size:
      /* 1 numeric unsigned argument. */
      printf ("%s(%" PRIu64 ")", opname, expr->number);
      break;

    case DW_OP_call2:
    case DW_OP_call4:
    case DW_OP_call_ref:
      /* 1 DIE offset argument for more ops in location attribute of DIE.
         Never used in CFI.  */
      {
	if (attr == NULL)
	  error (EXIT_FAILURE, 0, "%s used in CFI", opname);

	Dwarf_Attribute call_attr;
	if (dwarf_getlocation_attr (attr, expr, &call_attr) != 0)
	  error (EXIT_FAILURE, 0, "dwarf_getlocation_attr for %s error %s",
		 opname, dwarf_errmsg (-1));

	Dwarf_Die call_die;
	if (dwarf_getlocation_die (attr, expr, &call_die) != 0)
	  error (EXIT_FAILURE, 0, "dwarf_getlocation_die for %s error %s",
		 opname, dwarf_errmsg (-1));

	Dwarf_Op *call_ops;
	size_t call_len;
	if (dwarf_getlocation (&call_attr, &call_ops, &call_len) != 0)
	  error (EXIT_FAILURE, 0, "dwarf_getlocation for entry: %s",
		 dwarf_errmsg (-1));

	printf ("%s([%" PRIx64 "]) ", opname, dwarf_dieoffset (&call_die));
	print_expr_block (&call_attr, call_ops, call_len, addr);
      }
      break;

    case DW_OP_const1s:
    case DW_OP_const2s:
    case DW_OP_const4s:
    case DW_OP_const8s:
    case DW_OP_consts:
    case DW_OP_skip:
    case DW_OP_bra:
    case DW_OP_breg0 ... DW_OP_breg31:
      /* 1 numeric signed argument. */
      printf ("%s(%" PRId64 ")", opname, (Dwarf_Sword) expr->number);
      break;

    case DW_OP_fbreg:
      /* 1 numeric signed argument. Offset from frame base. */
      if (attr == NULL)
	  error (EXIT_FAILURE, 0, "%s used in CFI", opname);

      if (! has_frame_base)
	error (EXIT_FAILURE, 0, "DW_OP_fbreg used without a frame base");

      printf ("%s(%" PRId64 ")", opname, (Dwarf_Sword) expr->number);
      break;

    case DW_OP_bregx:
      /* 2 arguments, unsigned register number, signed offset. */
      printf ("%s(%" PRIu64 ",%" PRId64 ")", opname,
	      expr->number, (Dwarf_Sword) expr->number2);
      break;

    case DW_OP_bit_piece:
      /* 2 arguments, unsigned size, unsigned offset. */
      printf ("%s(%" PRIu64 ",%" PRIu64 ")", opname,
	      expr->number, expr->number2);
      break;

    case DW_OP_implicit_value:
      /* Special, unsigned size plus block. */
      {
	Dwarf_Attribute const_attr;
	Dwarf_Block block;
	if (dwarf_getlocation_attr (attr, expr, &const_attr) != 0)
	  error (EXIT_FAILURE, 0, "dwarf_getlocation_attr: %s",
		 dwarf_errmsg (-1));

	if (dwarf_formblock (&const_attr, &block) != 0)
	  error (EXIT_FAILURE, 0, "dwarf_formblock: %s",
		 dwarf_errmsg (-1));

	/* This is the "old" way. Check they result in the same.  */
	Dwarf_Block block_impl;
	if (dwarf_getlocation_implicit_value (attr, expr, &block_impl) != 0)
	  error (EXIT_FAILURE, 0, "dwarf_getlocation_implicit_value: %s",
		 dwarf_errmsg (-1));

	assert (expr->number == block.length);
	assert (block.length == block_impl.length);
	printf ("%s(%" PRIu64 "){", opname, block.length);
	for (size_t i = 0; i < block.length; i++)
	  {
	    printf ("%02x", block.data[i]);
	    assert (block.data[i] == block_impl.data[i]);
	  }
	printf("}");
      }
      break;

    case DW_OP_GNU_implicit_pointer:
      /* Special, DIE offset, signed offset. Referenced DIE has a
	 location or const_value attribute. */
      {
	if (attr == NULL)
	  error (EXIT_FAILURE, 0, "%s used in CFI", opname);

	Dwarf_Attribute attrval;
	if (dwarf_getlocation_implicit_pointer (attr, expr, &attrval) != 0)
	  error (EXIT_FAILURE, 0, "dwarf_getlocation_implicit_pointer: %s",
		 dwarf_errmsg (-1));

	// Sanity check, results should be the same.
	Dwarf_Attribute attrval2;
	if (dwarf_getlocation_attr (attr, expr, &attrval2) != 0)
	  error (EXIT_FAILURE, 0, "dwarf_getlocation_attr: %s",
		 dwarf_errmsg (-1));

	assert (dwarf_whatattr (&attrval) == dwarf_whatattr (&attrval2));
	assert (dwarf_whatform (&attrval) == dwarf_whatform (&attrval2));
	// In theory two different valp pointers could point to the same
	// value. But here we really expect them to be the equal.
	assert (attrval.valp == attrval2.valp);

	Dwarf_Die impl_die;
	if (dwarf_getlocation_die (attr, expr, &impl_die) != 0)
	  error (EXIT_FAILURE, 0, "dwarf_getlocation_due: %s",
		 dwarf_errmsg (-1));

	printf ("%s([%" PRIx64 "],%" PRId64 ") ", opname,
		dwarf_dieoffset (&impl_die), expr->number2);

	if (dwarf_whatattr (&attrval) == DW_AT_const_value)
	  printf ("<constant value>"); // Lookup type...
	else
	  {
	    // Lookup the location description at the current address.
	    Dwarf_Op *exprval;
	    size_t exprval_len;
	    int locs = dwarf_getlocation_addr (&attrval, addr,
					       &exprval, &exprval_len, 1);
	    if (locs == 0)
	      printf ("<no location>"); // This means "optimized out".
	    else if (locs == 1)
	      print_expr_block (&attrval, exprval, exprval_len, addr);
	    else
	      error (EXIT_FAILURE, 0,
		     "dwarf_getlocation_addr attrval at addr 0x%" PRIx64
		     ", locs (%d): %s", addr, locs, dwarf_errmsg (-1));
	  }
      }
      break;

    case DW_OP_GNU_entry_value:
      /* Special, unsigned size plus expression block. All registers
	 inside the block should be interpreted as they had on
	 entering the function. dwarf_getlocation_attr will return an
	 attribute containing the block as locexpr which can be
	 retrieved with dwarf_getlocation.  */
      {
	Dwarf_Attribute entry_attr;
	if (dwarf_getlocation_attr (attr, expr, &entry_attr) != 0)
	  error (EXIT_FAILURE, 0, "dwarf_getlocation_attr: %s",
		 dwarf_errmsg (-1));

	Dwarf_Op *entry_ops;
	size_t entry_len;
	if (dwarf_getlocation (&entry_attr, &entry_ops, &entry_len) != 0)
	  error (EXIT_FAILURE, 0, "dwarf_getlocation for entry: %s",
		 dwarf_errmsg (-1));

	printf ("%s(%zd) ", opname, entry_len);
	print_expr_block (attr, entry_ops, entry_len, addr);
      }
      break;

    case DW_OP_GNU_parameter_ref:
      /* Special, unsigned CU relative DIE offset pointing to a
	 DW_TAG_formal_parameter. The value that parameter had at the
	 call site of the current function will be put on the DWARF
	 stack. The value can be retrieved by finding the
	 DW_TAG_GNU_call_site_parameter which has as
	 DW_AT_abstract_origin the same formal parameter DIE. */
      {
	Dwarf_Die param;
	if (dwarf_getlocation_die (attr, expr, &param) != 0)
	  error (EXIT_FAILURE, 0, "dwarf_getlocation_die: %s",
		 dwarf_errmsg (-1));
	// XXX actually lookup DW_TAG_GNU_call_site_parameter
	printf ("%s[%" PRIx64 "]", opname, dwarf_dieoffset (&param));
	assert (expr->number == dwarf_cuoffset (&param));
	assert (dwarf_tag (&param) == DW_TAG_formal_parameter);
      }
      break;

    case DW_OP_GNU_convert:
    case DW_OP_GNU_reinterpret:
      /* Special, unsigned CU relative DIE offset pointing to a
	 DW_TAG_base_type. Pops a value, converts or reinterprets the
	 value to the given type. When the argument is zero the value
	 becomes untyped again. */
      {
	Dwarf_Die type;
	Dwarf_Off off = expr->number;
	if (off != 0)
	  {
	    if (dwarf_getlocation_die (attr, expr, &type) != 0)
	      error (EXIT_FAILURE, 0, "dwarf_getlocation_die: %s",
		     dwarf_errmsg (-1));
	    off = dwarf_dieoffset (&type);
	    assert (expr->number == dwarf_cuoffset (&type));
	    printf ("%s", opname);
	    print_base_type (&type);
	  }
	else
	  printf ("%s[%" PRIu64 "]", opname, off);

      }
      break;

    case DW_OP_GNU_regval_type:
      /* Special, unsigned register number plus unsigned CU relative
         DIE offset pointing to a DW_TAG_base_type. */
      {
	Dwarf_Die type;
	if (dwarf_getlocation_die (attr, expr, &type) != 0)
	  error (EXIT_FAILURE, 0, "dwarf_getlocation_die: %s",
		 dwarf_errmsg (-1));
	assert (expr->number2 == dwarf_cuoffset (&type));
	// XXX check size against base_type size?
	printf ("%s(reg%" PRIu64 ")", opname, expr->number);
	print_base_type (&type);
      }
      break;

    case DW_OP_GNU_deref_type:
      /* Special, unsigned size plus unsigned CU relative DIE offset
	 pointing to a DW_TAG_base_type. */ 
      {
	Dwarf_Die type;
	if (dwarf_getlocation_die (attr, expr, &type) != 0)
	  error (EXIT_FAILURE, 0, "dwarf_getlocation_die: %s",
		 dwarf_errmsg (-1));
	assert (expr->number2 == dwarf_cuoffset (&type));
	// XXX check size against base_type size?
	printf ("%s(%" PRIu64 ")", opname, expr->number);
	print_base_type (&type);
      }
      break;

    case DW_OP_GNU_const_type:
      /* Special, unsigned CU relative DIE offset pointing to a
	 DW_TAG_base_type, an unsigned size length plus a block with
	 the constant value. */
      {
	Dwarf_Die type;
	if (dwarf_getlocation_die (attr, expr, &type) != 0)
	  error (EXIT_FAILURE, 0, "dwarf_getlocation_die: %s",
		 dwarf_errmsg (-1));
	assert (expr->number == dwarf_cuoffset (&type));

	Dwarf_Attribute const_attr;
	if (dwarf_getlocation_attr (attr, expr, &const_attr) != 0)
	  error (EXIT_FAILURE, 0, "dwarf_getlocation_attr for type: %s",
		 dwarf_errmsg (-1));
	  
	Dwarf_Block block;
	if (dwarf_formblock (&const_attr, &block) != 0)
	  error (EXIT_FAILURE, 0, "dwarf_formblock for type: %s",
		 dwarf_errmsg (-1));

	printf ("%s", opname);
	print_base_type (&type);
	printf ("(%" PRIu64 ")[", block.length);
	for (size_t i = 0; i < block.length; i++)
	  printf ("%02x", block.data[i]);
	printf("]");
      }
      break;

    default:
      error (EXIT_FAILURE, 0, "unhandled opcode: DW_OP_%s (0x%x)",
	     opname, atom);
    }
}
Exemplo n.º 15
0
/* get_compiler_info */
int get_compiler_info(void) {
    Dwarf_Unsigned   cu_header_length, abbrev_offset, next_cu_header;
    Dwarf_Half       version, address_size;
    Dwarf_Signed     attrcount, i, language;
    Dwarf_Die        no_die = 0, cu_die;
    Dwarf_Attribute *attrs;
    Dwarf_Half       attrcode;
    Dwarf_Debug      dbg = 0;
    Dwarf_Error      err;
    char *compiler = NULL;
    int fd = -1;

    OUTPUT_VERBOSE((5, "%s", _BLUE("Extracting DWARF info")));

    /* Open the binary */
    if (0 > (fd = open(globals.program_full, O_RDONLY))) {
        OUTPUT(("%s [%s]", _ERROR("opening program binary"),
            globals.program_full));
        return PERFEXPERT_ERROR;
    }

    /* Initialize DWARF library  */
    if (DW_DLV_OK != dwarf_init(fd, DW_DLC_READ, 0, 0, &dbg, &err)) {
        OUTPUT(("%s", _ERROR("failed DWARF initialization")));
        return PERFEXPERT_ERROR;
    }

    /* Find compilation unit header */
    if (DW_DLV_ERROR == dwarf_next_cu_header(dbg, &cu_header_length,
        &version, &abbrev_offset, &address_size, &next_cu_header, &err)) {
        OUTPUT(("%s", _ERROR("reading DWARF CU header")));
        return PERFEXPERT_ERROR;
    }

    /* Expect the CU to have a single sibling, a DIE */
    if (DW_DLV_ERROR == dwarf_siblingof(dbg, no_die, &cu_die, &err)) {
        OUTPUT(("%s", _ERROR("getting sibling of CU")));
        return PERFEXPERT_ERROR;
    }

    /* Find the DIEs attributes */
    if (DW_DLV_OK != dwarf_attrlist(cu_die, &attrs, &attrcount, &err)) {
        OUTPUT(("%s", _ERROR("in dwarf_attlist")));
        return PERFEXPERT_ERROR;
    }

    /* For each attribute... */
    for (i = 0; i < attrcount; ++i) {
        if (DW_DLV_OK != dwarf_whatattr(attrs[i], &attrcode, &err)) {
            OUTPUT(("%s [%s]", _ERROR("in dwarf_whatattr")));
            return PERFEXPERT_ERROR;
        }
        if (DW_AT_producer == attrcode) {
            if (DW_DLV_OK != dwarf_formstring(attrs[i], &compiler, &err)) {
                OUTPUT(("%s [%s]", _ERROR("in dwarf_formstring")));
                return PERFEXPERT_ERROR;
            } else {
                OUTPUT_VERBOSE((5, "   Compiler: %s", _CYAN(compiler)));
            }
        }
        if (DW_AT_language == attrcode) {
            if (DW_DLV_OK != dwarf_formsdata(attrs[i], &language, &err)) {
                OUTPUT(("%s [%s]", _ERROR("in dwarf_formsdata")));
                return PERFEXPERT_ERROR;
            } else {
                OUTPUT_VERBOSE((5, "   Language: %d", language));
            }
        }
    }

    if (PERFEXPERT_SUCCESS != database_write(compiler, language)) {
        OUTPUT(("%s", _ERROR("writing to database")));
        return PERFEXPERT_ERROR;
    }

    /* Finalize DWARF library  */
    if (DW_DLV_OK != dwarf_finish(dbg, &err)) {
        OUTPUT(("%s", _ERROR("failed DWARF finalization")));
        return PERFEXPERT_ERROR;
    }

    close(fd);

    return PERFEXPERT_SUCCESS;
}
Exemplo n.º 16
0
static void
_dwarf_attr(Dwarf_Die die)
{
	Dwarf_Attribute at;
	Dwarf_Bool has_attr;
	Dwarf_Half attr;
	Dwarf_Error de;
	const char *attr_name;
	int i, r;

	for (i = 0; i < attr_array_size; i++) {
		if (dwarf_hasattr(die, attr_array[i], &has_attr, &de) !=
		    DW_DLV_OK) {
			tet_printf("dwarf_hasattr failed: %s\n",
			    dwarf_errmsg(de));
			result = TET_FAIL;
		}
		TS_CHECK_INT(has_attr);

		if (has_attr) {
			if (dwarf_get_AT_name(attr_array[i], &attr_name) !=
			    DW_DLV_OK) {
				tet_printf("dwarf_get_AT_name failed: %s\n",
				    dwarf_errmsg(de));
				result = TET_FAIL;
				continue;
			}
			if (attr_name == NULL) {
				tet_infoline("dwarf_get_AT_name returned "
				    "DW_DLV_OK but didn't return string");
				result = TET_FAIL;
				continue;
			}
			TS_CHECK_STRING(attr_name);

			tet_printf("DIE #%d has attribute '%s'\n", die_cnt,
			    attr_name);

			r = dwarf_attr(die, attr_array[i], &at, &de);
			if (r == DW_DLV_ERROR) {
				tet_printf("dwarf_attr failed: %s",
				    dwarf_errmsg(de));
				result = TET_FAIL;
				continue;
			} else if (r == DW_DLV_NO_ENTRY) {
				tet_infoline("dwarf_hasattr returned true for "
				    "attribute '%s', while dwarf_attr returned"
				    " DW_DLV_NO_ENTRY for the same attr");
				result = TET_FAIL;
				continue;
			}
			if (dwarf_whatattr(at, &attr, &de) != DW_DLV_OK) {
				tet_printf("dwarf_whatattr failed: %s",
				    dwarf_errmsg(de));
				result = TET_FAIL;
				continue;
			}
			if (attr != attr_array[i]) {
				tet_infoline("attr returned by dwarf_whatattr"
				    " != attr_array[i]");
				result = TET_FAIL;
				continue;
			}
		}
	}
}
Exemplo n.º 17
0
static void show_all_attrs(Dwarf_Die die, unsigned long level, void *ndata){
  Dwarf_Error error;
  Dwarf_Half tag; 
  dwarf_tag(die,&tag,&error);

  const char *stag;
  dwarf_get_TAG_name(tag,&stag); 

  Dwarf_Off off = 0x0;
  dwarf_die_CU_offset(die,&off,&error);
  fprintf(stderr,"[%u]<%x>%s\n",level,off,stag);
  
  char **sourceFiles;
  Dwarf_Signed num;
  int res;
  if( (res = dwarf_srcfiles(die,&sourceFiles,&num,&error)) == DW_DLV_OK){
    fprintf(stderr,"Source Files Referenced:\n");
    int i;
    for(i = 0; i < num; i++){
      fprintf(stderr,"%s\n",sourceFiles[i]);
      dwarf_dealloc(d, sourceFiles[i],DW_DLA_STRING);
    } 
    dwarf_dealloc(d, sourceFiles,DW_DLA_LIST);
  }

  Dwarf_Unsigned atcnt;
  Dwarf_Attribute *atlist;
  int errv;
  if((errv = dwarf_attrlist(die, &atlist, &atcnt, &error)) == DW_DLV_OK){
    int i;
    for(i = 0; i < atcnt; i++){
      Dwarf_Half attr;
      if(dwarf_whatattr(atlist[i],&attr,&error) == DW_DLV_OK){
        const char *sattr;
        dwarf_get_AT_name(attr,&sattr); 
        fprintf(stderr,"\t%s => ",sattr);
      }else{
        fprintf(stderr,"\tCouldn't Get Attr Type!\n"); 
        continue;
      }
      Dwarf_Half form;
      if(dwarf_whatform(atlist[i],&form,&error) == DW_DLV_OK){
        //const char *formname;
        //dwarf_get_FORM_name(form,&formname);
        //fprintf(stderr,"[%s] ",formname);
        switch(form){
          case DW_FORM_ref1:
          case DW_FORM_ref2:
          case DW_FORM_ref4:
          case DW_FORM_ref8:
          case DW_FORM_ref_udata:
            {Dwarf_Off offset;
            dwarf_formref(atlist[i],&offset,&error); 
            fprintf(stderr,"%x\n",offset);}
            break;
          case DW_FORM_ref_addr:
            {Dwarf_Off offset;
            dwarf_global_formref(atlist[i],&offset,&error); 
            fprintf(stderr,"%x\n",offset);}
            break;
          case DW_FORM_addr:
            {Dwarf_Addr addr;
            dwarf_formaddr(atlist[i],&addr,&error); 
            fprintf(stderr,"%x\n",addr);}
            break;
          case DW_FORM_flag:
            {Dwarf_Bool flag;
            dwarf_formflag(atlist[i],&flag,&error); 
            fprintf(stderr,"%s\n",flag ? "True" : "False");}
            break;
          case DW_FORM_udata:
          case DW_FORM_data1:
          case DW_FORM_data2:
          case DW_FORM_data4:
          case DW_FORM_data8:
            {Dwarf_Unsigned val;
            dwarf_formudata(atlist[i],&val,&error); 
            fprintf(stderr,"%u\n",val);}
            break;
          case DW_FORM_sdata:
            {Dwarf_Signed val;
            dwarf_formsdata(atlist[i],&val,&error); 
            fprintf(stderr,"%d\n",val);}
            break;
          case DW_FORM_block:
          case DW_FORM_block1:
            if(attr == DW_AT_location ||
               attr == DW_AT_data_member_location ||
               attr == DW_AT_vtable_elem_location ||
               attr == DW_AT_string_length ||
               attr == DW_AT_use_location ||
               attr == DW_AT_return_addr){
              /* 
              Dwarf_Locdesc *locationList;
              Dwarf_Signed listLength;
              int ret = dwarf_loclist( atlist[i], &locationList, &listLength, &error );
              int frameRel = 0;
              long offset = 0;
              decode_location(locationList,listLength,&offset,NULL,&frameRel);
              int i;
              for( i = 0; i < listLength; ++i){
                dwarf_dealloc(d,locationList[i].ld_s,DW_DLA_LOC_BLOCK);               
              }
              dwarf_dealloc(d,locationList,DW_DLA_LOCDESC);               
              */
              DC_location dcl;
              DC_get_location_attr_value(atlist[i],&dcl); 
              fprintf(stderr," %s:",dcl.isFrameOffset ? "FP Offset" : "Address");
              fprintf(stderr," %ld\n",dcl.offset);

            }else{
              fprintf(stderr,"UNSUPPORTED ATTRIBUTE TYPE\n");
            }
            break;
          case DW_FORM_string:
            {char *val;
            dwarf_formstring(atlist[i],&val,&error); 
            fprintf(stderr,"%s\n",val);}
            break;
          
          case DW_FORM_strp:
            {char *str;
            if( (dwarf_formstring(atlist[i],&str,&error) == DW_DLV_OK) ){
              fprintf(stderr,"%s\n",str);
            } }
            break;
          
          default:
            fprintf(stderr,"Unhandled Attribute Form!\n");
            break;
            
        };
      }
      dwarf_dealloc(d, atlist[i], DW_DLA_ATTR);
    }
    dwarf_dealloc(d, atlist, DW_DLA_LIST);
  } 

}
Exemplo n.º 18
0
error_t print_local_var(mygdb_info_t* gdb_info, Dwarf_Die var_die, char* var_name){
	Dwarf_Half tag;
	Dwarf_Error err;
	unsigned long var_addr;
	Dwarf_Attribute* attrs;
	Dwarf_Locdesc* locs_var;
	Dwarf_Signed attrcount, i, cnt_var;
	
	if (dwarf_tag(var_die, &tag, &err) != DW_DLV_OK)
		return E_FATAL;

	/* Make sure to only have a var die */
	if (tag != DW_TAG_variable)
		return E_FATAL;
		
		/* Grab the DIEs attributes */
	if (dwarf_attrlist(var_die, &attrs, &attrcount, &err) != DW_DLV_OK)
		return E_FATAL;
	
	for (i = 0; i < attrcount; ++i) {
		Dwarf_Half attrcode;
		if (dwarf_whatattr(attrs[i], &attrcode, &err) != DW_DLV_OK)
			return E_FATAL;

		
		if (attrcode == DW_AT_location)
			break;
		
	}
	
	if( attrs[i] == NULL ){
		printf("Failed to find the DW_AT_location attribute\n");
		return E_NON_FATAL;
	}
	
	if( dwarf_loclist(attrs[i], &locs_var, &cnt_var, &err) != DW_DLV_OK){
		printf("dwarf_loclist failed\n");
		return E_FATAL;
	}
	
	if((cnt_var != 1) || (locs_var[0].ld_cents != 1) || (locs_var[0].ld_s[0].lr_atom != DW_OP_fbreg)){
		fprintf(stderr, "Unexpected location information\n");
		return E_NON_FATAL;
  	}
  	
  	struct user_regs_struct regs;
  	if( ptrace(PTRACE_GETREGS, gdb_info->child_pid, NULL, &regs ) < 0 )
  		return E_FATAL;
  		
  		var_addr = (unsigned long)(regs.rbp + (long)locs_var[0].ld_s[0].lr_number + 16);
		
		errno = 0;
		unsigned long data;
		data = ptrace(PTRACE_PEEKTEXT, gdb_info->child_pid, (void*)var_addr);
		
		if(errno){
			printf("peektext failed\n");
			return E_FATAL;
		}
		
		printf("%s = %lu\n", var_name, data);
		
	return E_NONE;
}