示例#1
0
文件: dwarf.c 项目: taocp/c-debugger
/* 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);
}
示例#2
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;

}
示例#3
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;
  
}
示例#4
0
static uint64_t MC_dwarf_attr_integrate_addr(Dwarf_Die * die, int attribute)
{
  Dwarf_Attribute attr;
  if (dwarf_attr_integrate(die, attribute, &attr) == nullptr)
    return 0;
  Dwarf_Addr value;
  if (dwarf_formaddr(&attr, &value) == 0)
    return (uint64_t) value;
  else
    return 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;
}
示例#6
0
Dwarf_Addr DieHolder::get_addr_from_attr(int attr)
{
  Dwarf_Addr addr = 0;
  Dwarf_Error err = NULL;
  Dwarf_Attribute attrib = get_attr(attr);

  CHECK_DWERR2(attrib == NULL, NULL, "cannot find DIE attribute %d\n", attr);
  CHECK_DWERR(dwarf_formaddr(attrib, &addr, &err), err,
              "cannot get address");

  return addr;
}
static void
get_addr(Dwarf_Attribute attr,Dwarf_Addr *val)
{
    Dwarf_Error error = 0;
    int res;
    Dwarf_Addr uval = 0;
    res = dwarf_formaddr(attr,&uval,&error);
    if(res == DW_DLV_OK) {
        *val = uval;
        return;
    }
    return;
}
示例#8
0
static void MC_dwarf_handle_scope_die(simgrid::mc::ObjectInformation* info, Dwarf_Die * die,
                                      Dwarf_Die * unit, simgrid::mc::Frame* parent_frame,
                                      const char *ns)
{
  // TODO, handle DW_TAG_type/DW_TAG_location for DW_TAG_with_stmt
  int tag = dwarf_tag(die);
  simgrid::dwarf::TagClass klass = simgrid::dwarf::classify_tag(tag);

  // (Template) Subprogram declaration:
  if (klass == simgrid::dwarf::TagClass::Subprogram
      && MC_dwarf_attr_flag(die, DW_AT_declaration, false))
    return;

  if (klass == simgrid::dwarf::TagClass::Scope)
    xbt_assert(parent_frame, "No parent scope for this scope");

  simgrid::mc::Frame frame;
  frame.tag = tag;
  frame.id = dwarf_dieoffset(die);
  frame.object_info = info;

  if (klass == simgrid::dwarf::TagClass::Subprogram) {
    const char *name = MC_dwarf_attr_integrate_string(die, DW_AT_name);
    if (name && ns)
      frame.name  = std::string(ns) + "::" + name;
    else if (name)
      frame.name = name;
  }

  frame.abstract_origin_id =
    MC_dwarf_attr_dieoffset(die, DW_AT_abstract_origin);

  // This is the base address for DWARF addresses.
  // Relocated addresses are offset from this base address.
  // See DWARF4 spec 7.5
  std::uint64_t base = (std::uint64_t) info->base_address();

  // TODO, support DW_AT_ranges
  uint64_t low_pc = MC_dwarf_attr_integrate_addr(die, DW_AT_low_pc);
  frame.range.begin() = low_pc ? (std::uint64_t) base + low_pc : 0;
  if (low_pc) {
    // DW_AT_high_pc:
    Dwarf_Attribute attr;
    if (not dwarf_attr_integrate(die, DW_AT_high_pc, &attr))
      xbt_die("Missing DW_AT_high_pc matching with DW_AT_low_pc");

    Dwarf_Sword offset;
    Dwarf_Addr high_pc;

    switch (simgrid::dwarf::classify_form(dwarf_whatform(&attr))) {

      // DW_AT_high_pc if an offset from the low_pc:
    case simgrid::dwarf::FormClass::Constant:

      if (dwarf_formsdata(&attr, &offset) != 0)
        xbt_die("Could not read constant");
      frame.range.end() = frame.range.begin() + offset;
      break;

      // DW_AT_high_pc is a relocatable address:
    case simgrid::dwarf::FormClass::Address:
      if (dwarf_formaddr(&attr, &high_pc) != 0)
        xbt_die("Could not read address");
      frame.range.end() = base + high_pc;
      break;

    default:
      xbt_die("Unexpected class for DW_AT_high_pc");

    }
  }

  if (klass == simgrid::dwarf::TagClass::Subprogram) {
    Dwarf_Attribute attr_frame_base;
    if (dwarf_attr_integrate(die, DW_AT_frame_base, &attr_frame_base))
      frame.frame_base_location = simgrid::dwarf::location_list(*info,
                                  attr_frame_base);
  }

  // Handle children:
  MC_dwarf_handle_children(info, die, unit, &frame, ns);

  // We sort them in order to have an (somewhat) efficient by name
  // lookup:
  boost::range::sort(frame.variables, MC_compare_variable);

  // Register it:
  if (klass == simgrid::dwarf::TagClass::Subprogram)
    info->subprograms[frame.id] = std::move(frame);
  else if (klass == simgrid::dwarf::TagClass::Scope)
    parent_frame->scopes.push_back(std::move(frame));
}
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);
}
示例#10
0
/* Check whether the DIE is a function */
static int process_one_DIE(Dwarf_Debug dbg, Dwarf_Die die, int *is_func)
{
    Dwarf_Half tag;
    int ret;

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

    if (tag != DW_TAG_subprogram)
    {
        *is_func = 0;
    }
    else    /* The DIE is a function */
    {
        Dwarf_Attribute attr;
        Dwarf_Die child;
        Dwarf_Die sib_die;
        char *name;
        Dwarf_Addr pc;
        uint32_t *match_addr;

        *is_func = 1;

        /* Function name */
        ret = dwarf_diename(die, &name, NULL);
        if (ret == DW_DLV_ERROR)
        {
            fprintf(stderr, "SET dwarf: Error in dwarf_diename()\n");
            return 1;
        }
        if (ret == DW_DLV_NO_ENTRY)
            return 0; /* The DIE is a concrete inlined instance? */

        /* Entry PC */
        ret = dwarf_attr(die, DW_AT_low_pc, &attr, NULL);
        if (ret == DW_DLV_ERROR)
        {
            fprintf(stderr, "SET dwarf: Error in dwarf_attr()\n");
            return 1;
        }
        if (ret == DW_DLV_NO_ENTRY)
            return 0; /* The DIE is an inlined function */

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

        /* Get the index of "func_addr" */
        pc += local_offset;
        match_addr = (uint32_t*) bsearch(&pc, local_func_addr, local_func_len, sizeof(uint32_t), compare_u32);
        if (match_addr)
            local_func_idx = (match_addr - local_func_addr);
        else
            return 0;

        dwarf_dealloc(dbg, name, DW_DLA_STRING);
        /* Get the parameter(s) of this function */
        ret = dwarf_child(die, &child, NULL);
        if (ret == DW_DLV_ERROR)
        {
            fprintf(stderr, "SET dwarf: Error in dwarf_child()\n");
            return 1;
        }
        if (ret == DW_DLV_NO_ENTRY)
            return 0;

        while (1)
        {
            /* Check whether the DIE is a formal parameter */
            ret = dwarf_tag(child, &tag, NULL);
            if (ret != DW_DLV_OK)
            {
                fprintf(stderr, "SET dwarf: Error in dwarf_tag()\n");
                dwarf_dealloc(dbg, child, DW_DLA_DIE);
                return 1;
            }

            /* FIXME: break or continue? */
            if (tag != DW_TAG_formal_parameter)
                break;

            ret = parse_parameter(dbg, child);
            if(ret != 0)
            {
                dwarf_dealloc(dbg, child, DW_DLA_DIE);
                return 1;
            }
            
            ret = dwarf_siblingof(dbg, child, &sib_die, NULL);
            if (ret == DW_DLV_ERROR)
            {
                fprintf(stderr, "SET dwarf: Error in dwarf_siblingof()\n");
                dwarf_dealloc(dbg, child, DW_DLA_DIE);
                return 1;
            }
            if (ret == DW_DLV_NO_ENTRY)
                break;

            dwarf_dealloc(dbg, child, DW_DLA_DIE);

            child = sib_die;
        }
        dwarf_dealloc(dbg, child, DW_DLA_DIE);
    }
    return 0;
}
示例#11
0
QVariant DwarfDie::attributeLocal(Dwarf_Half attributeType) const
{
    Dwarf_Attribute attr;
    auto res = dwarf_attr(m_die, attributeType, &attr, nullptr);
    if (res != DW_DLV_OK)
        return {};

    Dwarf_Half formType;
    res = dwarf_whatform(attr, &formType, nullptr);
    if (res != DW_DLV_OK)
        return {};

    QVariant value;
    switch (formType) {
        case DW_FORM_data1:
        case DW_FORM_data2:
        case DW_FORM_data4:
        case DW_FORM_data8:
        case DW_FORM_udata:
        {
            Dwarf_Unsigned n;
            res = dwarf_formudata(attr, &n, nullptr);
            value = n;
            break;
        }
        case DW_FORM_sdata:
        {
            Dwarf_Signed n;
            res = dwarf_formsdata(attr, &n, nullptr);
            value = n;
            break;
        }
        case DW_FORM_string:
        case DW_FORM_strp:
        {
            char *str;
            res = dwarf_formstring(attr, &str, nullptr);
            value = QByteArray(str);
            break;
        }
        case DW_FORM_flag:
        case DW_FORM_flag_present:
        {
            Dwarf_Bool b;
            res = dwarf_formflag(attr, &b, nullptr);
            value = b ? true : false;
            break;
        }
        case DW_FORM_ref1:
        case DW_FORM_ref2:
        case DW_FORM_ref4:
        case DW_FORM_ref8:
        {
            Dwarf_Off offset;
            res = dwarf_global_formref(attr, &offset, nullptr);
            value = QVariant::fromValue(dwarfInfo()->dieAtOffset(offset));
            break;
        }
        case DW_FORM_sec_offset:
        {
            Dwarf_Off offset;
            res = dwarf_global_formref(attr, &offset, nullptr);
            value = offset;
            break;
        }
        case DW_FORM_addr:
        {
            Dwarf_Addr addr;
            res = dwarf_formaddr(attr, &addr, nullptr);
            value = addr;
            break;
        }
        case DW_FORM_exprloc:
        {
            Dwarf_Unsigned len;
            Dwarf_Ptr block;
            res = dwarf_formexprloc(attr, &len, &block, nullptr);
            value = QVariant::fromValue(DwarfExpression(block, len, dwarfInfo()->elfFile()->addressSize()));
            break;
        }
        default:
        {
            const char* formName;
            res = dwarf_get_FORM_name(formType, &formName);
            if (res != DW_DLV_OK)
                return {};
            value = QStringLiteral("TODO: ") + QString::fromLocal8Bit(formName);
            break;
        }
    }

    // post-process some well-known types
    switch (attributeType) {
        case DW_AT_decl_file:
        case DW_AT_call_file:
        {
            const auto fileIndex = value.value<Dwarf_Unsigned>();
            // index 0 means not present, TODO handle that
            value = compilationUnit()->sourceFileForIndex(fileIndex -1);
            break;
        }
        case DW_AT_ranges:
            value = QVariant::fromValue(DwarfRanges(this, value.toLongLong()));
            break;
        case DW_AT_accessibility:
            stringifyEnum(value, &dwarf_get_ACCESS_name);
            break;
        case DW_AT_language:
            stringifyEnum(value, &dwarf_get_LANG_name);
            break;
        case DW_AT_virtuality:
            value = QVariant::fromValue(static_cast<DwarfVirtuality>(value.toInt()));
            break;
        case DW_AT_visibility:
            stringifyEnum(value, &dwarf_get_VIS_name);
            break;
        case DW_AT_identifier_case:
            stringifyEnum(value, &dwarf_get_ID_name);
            break;
        case DW_AT_inline:
            stringifyEnum(value, &dwarf_get_INL_name);
            break;
        case DW_AT_encoding:
            stringifyEnum(value, &dwarf_get_ATE_name);
            break;
        case DW_AT_ordering:
            stringifyEnum(value, &dwarf_get_ORD_name);
            break;
        case DW_AT_calling_convention:
            stringifyEnum(value, &dwarf_get_CC_name);
            break;
        case DW_AT_discr_list:
            stringifyEnum(value, &dwarf_get_DSC_name);
            break;
        default:
            break;
    }

    return value;
}
示例#12
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);
  } 

}
示例#13
-1
文件: rdwarf.c 项目: kubo/rdwarf
static VALUE rd_attr_raw_value(VALUE self)
{
    rd_attr_t *attr = GetAttr(self);
    Dwarf_Half form;
    Dwarf_Error err;
    union {
        Dwarf_Addr addr;
        Dwarf_Off off;
        Dwarf_Unsigned udata;
        Dwarf_Signed sdata;
        Dwarf_Bool bool;
        char *str;
    } val;
    VALUE top;

    chkerr1(dwarf_whatform(attr->attr, &form, &err), &err, self);
    switch (form) {
    case DW_FORM_addr:
        chkerr1(dwarf_formaddr(attr->attr, &val.addr, &err), &err, self);
        return ULL2NUM(val.addr);
    case DW_FORM_ref1:
    case DW_FORM_ref2:
    case DW_FORM_ref4:
    case DW_FORM_ref8:
    case DW_FORM_ref_udata:
        chkerr1(dwarf_global_formref(attr->attr, &val.off, &err), &err, self);
        top = rb_ivar_get(self, id_at_top);
        return rdwarf_die_at(top, LL2NUM(val.off));
    case DW_FORM_data1:
    case DW_FORM_data2:
    case DW_FORM_data4:
    case DW_FORM_data8:
    case DW_FORM_udata:
        chkerr1(dwarf_formudata(attr->attr, &val.udata, &err), &err, self);
        return ULL2NUM(val.udata);
    case DW_FORM_sdata:
        chkerr1(dwarf_formsdata(attr->attr, &val.sdata, &err), &err, self);
        return LL2NUM(val.sdata);
    case DW_FORM_flag:
        chkerr1(dwarf_formflag(attr->attr, &val.bool, &err), &err, self);
        return val.bool ? Qtrue : Qfalse;
    case DW_FORM_strp:
    case DW_FORM_string:
        chkerr1(dwarf_formstring(attr->attr, &val.str, &err), &err, self);
        return rb_str_new_cstr(val.str);
    }
    return sym_unsupported_type;
}