Beispiel #1
0
static bool MC_dwarf_attr_flag(Dwarf_Die * die, int attribute, bool integrate)
{
  Dwarf_Attribute attr;
  if ((integrate ? dwarf_attr_integrate(die, attribute, &attr)
       : dwarf_attr(die, attribute, &attr)) == 0)
    return false;

  bool result;
  if (dwarf_formflag(&attr, &result))
    xbt_die("Unexpected form for attribute %s",
      simgrid::dwarf::attrname(attribute));
  return result;
}
Beispiel #2
0
Dwarf_Bool DieHolder::get_attr_flag(int attr)
{
  Dwarf_Attribute attrib = get_attr(attr);
  Dwarf_Bool flag = (attrib != NULL);

  if(flag)
  {
    Dwarf_Error err = NULL;

    CHECK_DWERR(dwarf_formflag(attrib, &flag, &err), err,
                "cannot retrieve flag from attr %d", attr);
  }

  return flag;
}
Beispiel #3
0
static int
die_bool(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Bool *valp, int req)
{
	Dwarf_Attribute attr;
	Dwarf_Bool val;

	if ((attr = die_attr(dw, die, name, req)) == NULL)
		return (0); /* die_attr will terminate for us if necessary */

	if (dwarf_formflag(attr, &val, &dw->dw_err) != DW_DLV_OK) {
		terminate("die %llu: failed to get bool (form 0x%x)\n",
		    die_off(dw, die), die_attr_form(dw, attr));
	}

	dwarf_dealloc(dw->dw_dw, attr, DW_DLA_ATTR);

	*valp = val;
	return (1);
}
Beispiel #4
0
int
ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
{
  /* Start with the function's type, and get the DW_AT_type attribute,
     which is the type of the return value.  */

  Dwarf_Attribute attr_mem;
  Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type,
						&attr_mem);
  if (attr == NULL)
    /* The function has no return value, like a `void' function in C.  */
    return 0;

  Dwarf_Die die_mem;
  Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
  int tag = dwarf_tag (typedie);

  /* Follow typedefs and qualifiers to get to the actual type.  */
  while (tag == DW_TAG_typedef
	 || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
	 || tag == DW_TAG_restrict_type || tag == DW_TAG_mutable_type)
    {
      attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
      typedie = dwarf_formref_die (attr, &die_mem);
      tag = dwarf_tag (typedie);
    }

  Dwarf_Word size;
  switch (tag)
    {
    case -1:
      return -1;

    case DW_TAG_subrange_type:
      if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
	{
	  attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
	  typedie = dwarf_formref_die (attr, &die_mem);
	  tag = dwarf_tag (typedie);
	}
      /* Fall through.  */

    case DW_TAG_base_type:
    case DW_TAG_enumeration_type:
    case DW_TAG_pointer_type:
    case DW_TAG_ptr_to_member_type:
      if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
						 &attr_mem), &size) != 0)
	{
	  if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
	    size = 4;
	  else
	    return -1;
	}
      if (size <= 8)
	{
	  if (tag == DW_TAG_base_type)
	    {
	      Dwarf_Word encoding;
	      if (dwarf_formudata (dwarf_attr_integrate (typedie,
							 DW_AT_encoding,
							 &attr_mem),
				   &encoding) != 0)
		return -1;
	      if (encoding == DW_ATE_float)
		{
		  *locp = loc_fpreg;
		  return nloc_fpreg;
		}
	    }
	intreg:
	  *locp = loc_intreg;
	  return size <= 4 ? nloc_intreg : nloc_intregpair;
	}

    aggregate:
      *locp = loc_aggregate;
      return nloc_aggregate;

    case DW_TAG_array_type:
      {
	bool is_vector;
	if (dwarf_formflag (dwarf_attr_integrate (typedie, DW_AT_GNU_vector,
						  &attr_mem), &is_vector) == 0
	    && is_vector
	    && dwarf_aggregate_size (typedie, &size) == 0)
	  switch (size)
	    {
	    case 16:
	      if (ppc_altivec_abi ())
		{
		  *locp = loc_vmxreg;
		  return nloc_vmxreg;
		}
	      *locp = loc_intreg;
	      return nloc_intregquad;
	    }
      }
      /* Fall through.  */

    case DW_TAG_structure_type:
    case DW_TAG_class_type:
    case DW_TAG_union_type:
      if (SVR4_STRUCT_RETURN
	  && dwarf_aggregate_size (typedie, &size) == 0
	  && size > 0 && size <= 8)
	goto intreg;
      goto aggregate;
    }

  /* XXX We don't have a good way to return specific errors from ebl calls.
     This value means we do not understand the type, but it is well-formed
     DWARF and might be valid.  */
  return -2;
}
Beispiel #5
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;
}
Beispiel #6
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);
  } 

}
Beispiel #7
0
static struct variable* analyze_variable(Dwarf_Die *die, Dwarf_Files *files,
                                         struct expr_context *ctx)
{
    int ret;
    Dwarf_Attribute at;
    struct variable* var;

    /* ignore declarations */
    if (dwarf_attr_integrate(die, DW_AT_declaration, &at) != NULL)
    {
        bool flag;
        ret = dwarf_formflag(&at, &flag);
        fail_if(ret == -1, "dwarf_formflag");
        if (flag)
            return NULL;
    }

    var = xalloc(sizeof(struct variable));
    analyze_name_location(die, files, &var->name, &var->loc);

    if (dwarf_attr_integrate(die, DW_AT_type, &at) != NULL)
    {
        Dwarf_Die type_die;
        if (dwarf_formref_die(&at, &type_die) == NULL)
            fail("dwarf_formref_die");
        analyze_type(&type_die, &(var->type));
    }

    if (dwarf_attr_integrate(die, DW_AT_const_value, &at) != NULL)
    {
        Dwarf_Word w;
        Dwarf_Block bl;
        unsigned int form = dwarf_whatform(&at);
        debug("variable %s has constant value of form %x", var->name, form);

        if (dwarf_formudata(&at, &w) == 0)
        {
            fail_if(sizeof(w) < var->type.width, "constant value too small");
            var->value = xalloc(var->type.width);
            memcpy(var->value, &w, var->type.width);
        }
        else if (dwarf_formblock(&at, &bl) == 0)
        {
            fail_if(bl.length < var->type.width, "constant value too small");
            var->value = xalloc(var->type.width);
            memcpy(var->value, bl.data, var->type.width);
        }
        else
        {
            warn("unable to get constant value of variable %x (form %x)", var->name, form);
        }
    }
    else if (dwarf_attr_integrate(die, DW_AT_location, &at) != NULL)
    {
        size_t exprlen;
        Dwarf_Op *expr;

        ret = dwarf_getlocation_addr(&at, ctx->ip, &expr, &exprlen, 1);
        if (ret != 1)
        {
            if (ret == -1)
                /* it seems that elfutils have some kind of problem with
                 * DW_OP_GNU_entry_value but that operation is useless for us
                 * anyway */
                warn("cannot get location for variable %s (ip: %lx), %s", var->name, ctx->ip, dwarf_errmsg(-1));
            else if (ret == 0)
                debug("no location available for variable %s (ip: %lx)", var->name, ctx->ip);
            else
                fail("unreachable reached");
            return var;
        }

        var->value = evaluate_loc_expr(expr, exprlen, ctx, var->type.width);
    }

    return var;
}