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

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

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

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

    }

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

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

  }

}
示例#2
0
/** \brief Initialize the location of a member of a type
 * (DW_AT_data_member_location of a DW_TAG_member).
 *
 *  \param  type   a type (struct, class)
 *  \param  member the member of the type
 *  \param  child  DIE of the member (DW_TAG_member)
 */
static void MC_dwarf_fill_member_location(
  simgrid::mc::Type* type, simgrid::mc::Member* member, Dwarf_Die * child)
{
  if (dwarf_hasattr(child, DW_AT_data_bit_offset))
    xbt_die("Can't groke DW_AT_data_bit_offset.");

  if (not dwarf_hasattr_integrate(child, DW_AT_data_member_location)) {
    if (type->type == DW_TAG_union_type)
      return;
    xbt_die
        ("Missing DW_AT_data_member_location field in DW_TAG_member %s of type <%"
         PRIx64 ">%s", member->name.c_str(),
         (uint64_t) type->id, type->name.c_str());
  }

  Dwarf_Attribute attr;
  dwarf_attr_integrate(child, DW_AT_data_member_location, &attr);
  int form = dwarf_whatform(&attr);
  simgrid::dwarf::FormClass form_class = simgrid::dwarf::classify_form(form);
  switch (form_class) {
  case simgrid::dwarf::FormClass::ExprLoc:
  case simgrid::dwarf::FormClass::Block:
    // Location expression:
    {
      Dwarf_Op *expr;
      size_t len;
      if (dwarf_getlocation(&attr, &expr, &len))
        xbt_die
            ("Could not read location expression DW_AT_data_member_location in DW_TAG_member %s of type <%"
             PRIx64 ">%s", MC_dwarf_attr_integrate_string(child, DW_AT_name),
             (uint64_t) type->id, type->name.c_str());
      member->location_expression = simgrid::dwarf::DwarfExpression(expr, expr+len);
      break;
    }
  case simgrid::dwarf::FormClass::Constant:
    // Offset from the base address of the object:
    {
      Dwarf_Word offset;
      if (not dwarf_formudata(&attr, &offset))
        member->offset(offset);
      else
        xbt_die("Cannot get %s location <%" PRIx64 ">%s",
                MC_dwarf_attr_integrate_string(child, DW_AT_name),
                (uint64_t) type->id, type->name.c_str());
      break;
    }

  default:
    // includes FormClass::LocListPtr (reference to a location list: TODO) and FormClass::Reference (it's supposed to be
    // possible in DWARF2 but I couldn't find its semantic in the spec)
    xbt_die("Can't handle form class (%d) / form 0x%x as DW_AT_member_location", (int)form_class, (unsigned)form);
  }

}
示例#3
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);
}
示例#4
0
static void
print_vars (unsigned int indent, Dwarf_Die *die)
{
  Dwarf_Die child;
  if (dwarf_child (die, &child) == 0)
    do
      switch (dwarf_tag (&child))
	{
	case DW_TAG_variable:
	case DW_TAG_formal_parameter:
	  printf ("%*s%-30s[%6" PRIx64 "]\n", indent, "",
		  dwarf_diename (&child),
		  (uint64_t) dwarf_dieoffset (&child));
	  break;
	default:
	  break;
	}
    while (dwarf_siblingof (&child, &child) == 0);

  Dwarf_Attribute attr_mem;
  Dwarf_Die origin;
  if (dwarf_hasattr (die, DW_AT_abstract_origin)
      && dwarf_formref_die (dwarf_attr (die, DW_AT_abstract_origin, &attr_mem),
			    &origin) != NULL
      && dwarf_child (&origin, &child) == 0)
    do
      switch (dwarf_tag (&child))
	{
	case DW_TAG_variable:
	case DW_TAG_formal_parameter:
	  printf ("%*s%s (abstract)\n", indent, "",
		  dwarf_diename (&child));
	  break;
	default:
	  break;
	}
    while (dwarf_siblingof (&child, &child) == 0);
}
示例#5
0
/* Get all the data in .debug_pubnames */
void
print_pubnames(Dwarf_Debug dbg)
{
    Dwarf_Global *globbuf = NULL;
    Dwarf_Signed count = 0;
    Dwarf_Signed i = 0;
    Dwarf_Off die_off = 0;
    Dwarf_Off cu_off = 0;

    /* Offset to previous CU */
    Dwarf_Off prev_cu_off = elf_max_address;

    char *name = 0;
    int res = 0;

    current_section_id = DEBUG_PUBNAMES;
    if (do_print_dwarf) {
        printf("\n.debug_pubnames\n");
    }
    res = dwarf_get_globals(dbg, &globbuf, &count, &err);
    if (res == DW_DLV_ERROR) {
        print_error(dbg, "dwarf_get_globals", res, err);
    } else if (res == DW_DLV_NO_ENTRY) {
        /*  (err == 0 && count == DW_DLV_NOCOUNT) means there are no
            pubnames.  */
    } else {
        Dwarf_Unsigned maxoff = get_info_max_offset(dbg);

        for (i = 0; i < count; i++) {
            int nres = 0;
            int cures3 = 0;
            Dwarf_Off global_cu_off = 0;

            nres = dwarf_global_name_offsets(globbuf[i],
                &name, &die_off, &cu_off,
                &err);
            deal_with_name_offset_err(dbg, "dwarf_global_name_offsets",
                name, die_off, nres, err);
            cures3 = dwarf_global_cu_offset(globbuf[i],
                &global_cu_off, &err);
            if (cures3 != DW_DLV_OK) {
                print_error(dbg, "dwarf_global_cu_offset", cures3, err);
            }

            if (check_pubname_attr) {
                Dwarf_Bool has_attr;
                int ares;
                int dres;
                Dwarf_Die die;

                /*  We are processing a new set of pubnames
                    for a different CU; get the producer ID, at 'cu_off'
                    to see if we need to skip these pubnames */
                if (cu_off != prev_cu_off) {

                    /* Record offset for previous CU */
                    prev_cu_off = cu_off;

                    dres = dwarf_offdie(dbg, cu_off, &die, &err);
                    if (dres != DW_DLV_OK) {
                        print_error(dbg, "print pubnames: dwarf_offdie a", dres,err);
                    }

                    {
                        /*  Get producer name for this CU
                            and update compiler list */
                        struct esb_s producername;
                        esb_constructor(&producername);
                        get_producer_name(dbg,die,err,&producername);
                        update_compiler_target(esb_get_string(&producername));
                        esb_destructor(&producername);
                    }

                    dwarf_dealloc(dbg, die, DW_DLA_DIE);
                }

                /* get die at die_off */
                dres = dwarf_offdie(dbg, die_off, &die, &err);
                if (dres != DW_DLV_OK) {
                    print_error(dbg, "print pubnames: dwarf_offdie b", dres, err);
                }


                ares =
                    dwarf_hasattr(die, DW_AT_external, &has_attr, &err);
                if (ares == DW_DLV_ERROR) {
                    print_error(dbg, "hassattr on DW_AT_external", ares,
                        err);
                }

                /*  Check for specific compiler */
                if (checking_this_compiler()) {
                    DWARF_CHECK_COUNT(pubname_attr_result,1);
                    if (ares == DW_DLV_OK && has_attr) {
                        /* Should the value of flag be examined? */
                    } else {
                        DWARF_CHECK_ERROR2(pubname_attr_result,name,
                            "pubname does not have DW_AT_external");
                    }
                }
                dwarf_dealloc(dbg, die, DW_DLA_DIE);
            }

            /* Now print pubname, after the test */
            if (do_print_dwarf || (record_dwarf_error && check_verbose_mode)) {
                print_pubname_style_entry(dbg,
                    "global",
                    name, die_off, cu_off,
                    global_cu_off, maxoff);
                record_dwarf_error = FALSE;  /* Clear error condition */
            }

        }
        dwarf_globals_dealloc(dbg, globbuf, count);
    }
}   /* print_pubnames() */
示例#6
0
static std::unique_ptr<simgrid::mc::Variable> MC_die_to_variable(
  simgrid::mc::ObjectInformation* info, Dwarf_Die * die,
  Dwarf_Die * unit, simgrid::mc::Frame* frame,
  const char *ns)
{
  // Skip declarations:
  if (MC_dwarf_attr_flag(die, DW_AT_declaration, false))
    return nullptr;

  // Skip compile time constants:
  if (dwarf_hasattr(die, DW_AT_const_value))
    return nullptr;

  Dwarf_Attribute attr_location;
  if (dwarf_attr(die, DW_AT_location, &attr_location) == nullptr)
    // No location: do not add it ?
    return nullptr;

  std::unique_ptr<simgrid::mc::Variable> variable =
    std::unique_ptr<simgrid::mc::Variable>(new simgrid::mc::Variable());
  variable->id = dwarf_dieoffset(die);
  variable->global = frame == nullptr;     // Can be override base on DW_AT_location
  variable->object_info = info;

  const char *name = MC_dwarf_attr_integrate_string(die, DW_AT_name);
  if (name)
    variable->name = name;
  variable->type_id = MC_dwarf_at_type(die);

  int form = dwarf_whatform(&attr_location);
  simgrid::dwarf::FormClass form_class;
  if (form == DW_FORM_sec_offset)
    form_class = simgrid::dwarf::FormClass::Constant;
  else
    form_class = simgrid::dwarf::classify_form(form);
  switch (form_class) {
  case simgrid::dwarf::FormClass::ExprLoc:
  case simgrid::dwarf::FormClass::Block:
    // Location expression:
    {
      Dwarf_Op *expr;
      size_t len;
      if (dwarf_getlocation(&attr_location, &expr, &len)) {
        xbt_die(
          "Could not read location expression in DW_AT_location "
          "of variable <%" PRIx64 ">%s",
          (uint64_t) variable->id,
          variable->name.c_str());
      }

      if (len == 1 && expr[0].atom == DW_OP_addr) {
        variable->global = true;
        uintptr_t offset = (uintptr_t) expr[0].number;
        uintptr_t base = (uintptr_t) info->base_address();
        variable->address = (void *) (base + offset);
      } else
        variable->location_list = {
            simgrid::dwarf::LocationListEntry(simgrid::dwarf::DwarfExpression(expr, expr + len))};

      break;
    }

  case simgrid::dwarf::FormClass::LocListPtr:
  case simgrid::dwarf::FormClass::Constant:
    // Reference to location list:
    variable->location_list = simgrid::dwarf::location_list(
      *info, attr_location);
    break;

  default:
    xbt_die("Unexpected form 0x%x (%i), class 0x%x (%i) list for location in <%" PRIx64 ">%s", (unsigned)form, form,
            (unsigned)form_class, (int)form_class, (uint64_t)variable->id, variable->name.c_str());
  }

  // Handle start_scope:
  if (dwarf_hasattr(die, DW_AT_start_scope)) {
    Dwarf_Attribute attr;
    dwarf_attr(die, DW_AT_start_scope, &attr);
    int form = dwarf_whatform(&attr);
    simgrid::dwarf::FormClass form_class = simgrid::dwarf::classify_form(form);
    if (form_class == simgrid::dwarf::FormClass::Constant) {
      Dwarf_Word value;
      variable->start_scope = dwarf_formudata(&attr, &value) == 0 ? (size_t)value : 0;
    } else {
      // TODO: FormClass::RangeListPtr
      xbt_die("Unhandled form 0x%x, class 0x%X for DW_AT_start_scope of variable %s", (unsigned)form,
              (unsigned)form_class, name == nullptr ? "?" : name);
    }
  }

  if (ns && variable->global)
    variable->name =
      std::string(ns) + "::" + variable->name;

  // The current code needs a variable name,
  // generate a fake one:
  if (variable->name.empty()) {
    variable->name = "@anonymous#" + std::to_string(mc_anonymous_variable_index);
    mc_anonymous_variable_index++;
  }
  return variable;
}
示例#7
0
/** \brief Populate the list of members of a type
 *
 *  \param info ELF object containing the type DIE
 *  \param die  DIE of the type
 *  \param unit DIE of the compilation unit containing the type DIE
 *  \param type the type
 */
static void MC_dwarf_add_members(simgrid::mc::ObjectInformation* info, Dwarf_Die * die,
                                 Dwarf_Die * unit, simgrid::mc::Type* type)
{
  int res;
  Dwarf_Die child;
  xbt_assert(type->members.empty());
  for (res = dwarf_child(die, &child); res == 0;
       res = dwarf_siblingof(&child, &child)) {
    int tag = dwarf_tag(&child);
    if (tag == DW_TAG_member || tag == DW_TAG_inheritance) {

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

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

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

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

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

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

      MC_dwarf_fill_member_location(type, &member, &child);

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

      type->members.push_back(std::move(member));
    }
  }
}
示例#8
0
/* Get all the data in .debug_static_funcs 
   On error, this allows some dwarf memory leaks.
*/
extern void
print_static_funcs(Dwarf_Debug dbg)
{
    Dwarf_Func *funcbuf = NULL;
    Dwarf_Signed count = 0;
    Dwarf_Signed i = 0;
    Dwarf_Off die_off = 0;
    Dwarf_Off cu_off = 0;
    int gfres = 0;

    printf("\n.debug_static_func\n");
    gfres = dwarf_get_funcs(dbg, &funcbuf, &count, &err);
    if (gfres == DW_DLV_ERROR) {
        print_error(dbg, "dwarf_get_funcs", gfres, err);
    } else if (gfres == DW_DLV_NO_ENTRY) {
        /* no static funcs */
    } else {
        Dwarf_Unsigned maxoff = get_info_max_offset(dbg);

        for (i = 0; i < count; i++) {
            int fnres;
            int cures3;
            Dwarf_Unsigned global_cu_off = 0;
            char *name = 0;

            fnres =
                dwarf_func_name_offsets(funcbuf[i], &name, &die_off,
                                        &cu_off, &err);
            deal_with_name_offset_err(dbg, "dwarf_func_name_offsets",
                                      name, die_off, fnres, err);

            cures3 = dwarf_func_cu_offset(funcbuf[i],
                                          &global_cu_off, &err);
            if (cures3 != DW_DLV_OK) {
                print_error(dbg, "dwarf_global_cu_offset", cures3, err);
            }

            print_pubname_style_entry(dbg,
                                      "static-func", name, die_off,
                                      cu_off, global_cu_off, maxoff);


            /* print associated die too? */
            if (check_pubname_attr) {
                Dwarf_Bool has_attr;
                int ares;
                int dres;
                Dwarf_Die die;

                /* get die at die_off */
                dres = dwarf_offdie(dbg, die_off, &die, &err);
                if (dres != DW_DLV_OK) {
                    print_error(dbg, "dwarf_offdie", dres, err);
                }


                ares =
                    dwarf_hasattr(die, DW_AT_external, &has_attr, &err);
                if (ares == DW_DLV_ERROR) {
                    print_error(dbg, "hassattr on DW_AT_external", ares,
                                err);
                }
                pubname_attr_result.checks++;
                if (ares == DW_DLV_OK && has_attr) {
                    /* Should the value of flag be examined? */
                } else {
                    DWARF_CHECK_ERROR2(pubname_attr_result,name,
                                       "pubname does not have DW_AT_external")
                }
                dwarf_dealloc(dbg, die, DW_DLA_DIE);
            }
        }
        dwarf_funcs_dealloc(dbg, funcbuf, count);
    }
}   /* print_static_funcs() */
示例#9
0
static void
structprobe(Dwarf *dw, Dwarf_Die *structdie)
{
	Dwarf_Die memdie;
	Dwarf_Word lastoff = 0, structsize;
	unsigned cline, members, nholes;
	size_t memsz, holesz;
	int x;

	(void)dw;

	cline = members = nholes = 0;
	memsz = holesz = 0;

	printf("struct %s {\n", dwarf_diename(structdie));

	if (dwarf_aggregate_size(structdie, &structsize) == -1)
		dwarf_err(EX_DATAERR, "dwarf_aggregate_size");

	if (dwarf_child(structdie, &memdie)) {
		printf("XXX ???\n");
		exit(EX_DATAERR);
	}

	do {
		Dwarf_Attribute type_attr, base_type_attr;
		Dwarf_Die type_die, base_type_die;
		char type_name[128], mem_name[128], ptr_suffix[32] = { '\0' };
		const char *type_tag = "";
		const char *type = NULL;
		unsigned type_ptrlevel = 0;

		Dwarf_Word msize, off;

		if (dwarf_tag(&memdie) != DW_TAG_member)
			continue;

		members++;
		/*
		 * TODO: Handle bitfield members. DW_AT_bit_offset,
		 * DW_AT_bit_size;
		 */

	 	/* Chase down the type die of this member */
		get_dwarf_attr(&memdie, DW_AT_type, &type_attr, &type_die);

		/* Member offset ... */
		if (get_member_offset(&memdie, &off) == -1)
			dwarf_err(EX_DATAERR, "%s", dwarf_diename(&memdie));

		/* Member size. */
		if (get_member_size(&type_die, &msize) == -1)
			dwarf_err(EX_DATAERR, "get_member_size");

		/* Format name; 'struct foo', 'enum bar', 'char **', etc. */
		if (isstruct(dwarf_tag(&type_die))) {
			type_tag = "struct ";
			type = dwarf_diename(&type_die);
		} else if (dwarf_tag(&type_die) == DW_TAG_enumeration_type) {
			type_tag = "enum ";
			type = dwarf_diename(&type_die);
		} else if (dwarf_tag(&type_die) == DW_TAG_pointer_type) {
			unsigned i;

			do {
				if (dwarf_tag(&type_die) == DW_TAG_pointer_type)
					type_ptrlevel++;
				else if (isstruct(dwarf_tag(&type_die)))
					type_tag = "struct ";
				else if (dwarf_tag(&type_die) == DW_TAG_enumeration_type)
					type_tag = "enum ";
				else
					printf("!!! XXX ignored pointer qualifier TAG %#x\n",
					    dwarf_tag(&type_die));

				/*
				 * Pointers to basic types still need some
				 * work. Clang doesn't emit an AT_TYPE for
				 * 'void*,' for example.
				 */
				if (!dwarf_hasattr(&type_die, DW_AT_type))
					break;

				get_dwarf_attr(&type_die, DW_AT_type,
				    &base_type_attr, &base_type_die);
				type_die = base_type_die;
				type_attr = base_type_attr;
			} while (dwarf_tag(&type_die) != DW_TAG_base_type);

			type = dwarf_diename(&type_die);
			if (type_ptrlevel > sizeof(ptr_suffix) - 2)
				type_ptrlevel = sizeof(ptr_suffix) - 2;
			ptr_suffix[0] = ' ';
			for (i = 1; i <= type_ptrlevel; i++)
				ptr_suffix[i] = '*';
			ptr_suffix[i] = '\0';
		} else
			type = dwarf_diename(&type_die);

		if (type == NULL)
			type = "<anonymous>";

		snprintf(type_name, sizeof(type_name), "%s%s%s", type_tag,
		    type, ptr_suffix);

		if (off != lastoff) {
			printf("\n\t/* XXX %ld bytes hole, try to pack */\n\n", off - lastoff);
			nholes++;
			holesz += (off - lastoff);
		}

		snprintf(mem_name, sizeof(mem_name), "%s;",
		    dwarf_diename(&memdie));

		printf("\t%-27s%-21s /* %5ld %5ld */\n", type_name, mem_name,
		    (long)off, (long)msize);
		memsz += msize;

		lastoff = off + msize;
		if (lastoff / cachelinesize > cline) {
			int ago = lastoff % cachelinesize;
			cline = lastoff / cachelinesize;

			if (ago)
				printf("\t/* --- cacheline %u boundary (%ld "
				    "bytes) was %d bytes ago --- */\n", cline,
				    (long)cline * cachelinesize, ago);
			else
				printf("\t/* --- cacheline %u boundary (%ld "
				    "bytes) --- */\n", cline, (long)cline *
				    cachelinesize);
		}
	} while ((x = dwarf_siblingof(&memdie, &memdie)) == 0);
	if (x == -1)
		dwarf_err(EX_DATAERR, "dwarf_siblingof");

	printf("\n\t/* size: %lu, cachelines: %u, members: %u */\n",
	    structsize, cline + 1, members);
	printf("\t/* sum members: %zu, holes: %u, sum holes: %zu */\n", memsz,
	    nholes, holesz);
	printf("\t/* last cacheline: %lu bytes */\n", lastoff % cachelinesize);

	printf("};\n");
}
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);
}
示例#11
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;
			}
		}
	}
}
/*
  Return DW_DLV_OK, or DW_DLV_ERROR

  Handle the addrs in a single die.
*/
static int
process_this_die_attrs(Dwarf_Debug dbg, Dwarf_Die newdie, int *errval)
{
    Dwarf_Error err;
    Dwarf_Half i;
    Dwarf_Half newattrnum;
    int res;
    int tres;
    Dwarf_Half ltag;

    Dwarf_Off doff;
    int doffres = dwarf_dieoffset(newdie, &doff, &err);

    if (doffres != DW_DLV_OK) {
	if (doffres == DW_DLV_ERROR) {
	    *errval = (int) dwarf_errno(err);
	}
	return doffres;
    }
    tres = dwarf_tag(newdie, &ltag, &err);
    if (tres != DW_DLV_OK) {
	return tres;
    }
    if (DW_TAG_compile_unit == ltag) {
	/* because of the way the dwarf_line code works, we ** do lines 
	   only per compile unit. ** This may turn out to be wrong if
	   we have lines ** left unconnected to a CU. ** of course such 
	   lines will not, at present, be ** used by gnome ** This is
	   not ideal as coded due to the dwarf_line.c issue. */
	int lres;

	lres = handle_debug_line(dbg, newdie, send_addr_note, errval);
	if (lres == DW_DLV_ERROR) {
	    return lres;
	}
    }

    for (i = 0; i < sizeof(might_have_addr) / sizeof(int); i++) {
	int resattr;
	Dwarf_Bool hasattr;

	newattrnum = might_have_addr[i];
	err = 0;
	resattr = dwarf_hasattr(newdie, newattrnum, &hasattr, &err);
	if (DW_DLV_OK == resattr) {
	    if (hasattr) {
		res = handle_attr_addr(dbg, newdie, newattrnum, &err);
		if (res != DW_DLV_OK) {
		    *errval = (int) dwarf_errno(err);
		    return DW_DLV_ERROR;
		}
	    }
	} else {
	    if (resattr == DW_DLV_ERROR) {
		*errval = (int) dwarf_errno(err);
		return resattr;
	    }
	}
    }
    for (i = 0; i < sizeof(might_have_locdesc) / sizeof(int); i++) {
	int resattr;
	Dwarf_Bool hasattr;

	newattrnum = might_have_locdesc[i];
	err = 0;
	resattr = dwarf_hasattr(newdie, newattrnum, &hasattr, &err);
	if (DW_DLV_OK == resattr) {
	    if (hasattr) {
		res =
		    handle_attr_locdesc(dbg, newdie, newattrnum, &err);
		if (res != DW_DLV_OK) {
		    *errval = (int) dwarf_errno(err);
		    return DW_DLV_ERROR;
		}
	    }
	} else {
	    if (resattr == DW_DLV_ERROR) {
		*errval = (int) dwarf_errno(err);
		return resattr;
	    }
	}
    }

    return DW_DLV_OK;
}
示例#13
0
/* Get all variables and print their value expressions. */
static void
print_varlocs (Dwarf_Die *funcdie)
{
  // Display frame base for function if it exists.
  // Should be used for DW_OP_fbreg.
  has_frame_base = dwarf_hasattr (funcdie, DW_AT_frame_base);
  if (has_frame_base)
    {
      Dwarf_Attribute fb_attr;
      if (dwarf_attr (funcdie, DW_AT_frame_base, &fb_attr) == NULL)
	error (EXIT_FAILURE, 0, "dwarf_attr fb: %s", dwarf_errmsg (-1));

      Dwarf_Op *fb_expr;
      size_t fb_exprlen;
      if (dwarf_getlocation (&fb_attr, &fb_expr, &fb_exprlen) == 0)
	{
	  // Covers all of function.
	  Dwarf_Addr entrypc;
	  if (dwarf_entrypc (funcdie, &entrypc) != 0)
	    error (EXIT_FAILURE, 0, "dwarf_entrypc: %s", dwarf_errmsg (-1));

	  printf ("    frame_base: ");
	  if (entrypc == 0)
	    printf ("XXX zero address"); // XXX bad DWARF?
	  else
	    print_expr_block (&fb_attr, fb_expr, fb_exprlen, entrypc);
	  printf ("\n");
	}
      else
	{
	  Dwarf_Addr base, start, end;
	  ptrdiff_t off = 0;
	  printf ("    frame_base:\n");
          while ((off = dwarf_getlocations (&fb_attr, off, &base,
					    &start, &end,
					    &fb_expr, &fb_exprlen)) > 0)
	    {
	      printf ("      (%" PRIx64 ",%" PRIx64 ") ", start, end);
	      print_expr_block (&fb_attr, fb_expr, fb_exprlen, start);
	      printf ("\n");
	    }

	  if (off < 0)
	    error (EXIT_FAILURE, 0, "dwarf_getlocations fb: %s",
		   dwarf_errmsg (-1));
	}
    }
  else if (dwarf_tag (funcdie) == DW_TAG_inlined_subroutine)
    {
      // See whether the subprogram we are inlined into has a frame
      // base we should use.
      Dwarf_Die *scopes;
      int n = dwarf_getscopes_die (funcdie, &scopes);
      if (n <= 0)
	error (EXIT_FAILURE, 0, "dwarf_getscopes_die: %s", dwarf_errmsg (-1));

      while (n-- > 0)
	if (dwarf_tag (&scopes[n]) == DW_TAG_subprogram
	    && dwarf_hasattr (&scopes[n], DW_AT_frame_base))
	  {
	    has_frame_base = true;
	    break;
	  }
      free (scopes);
    }

  if (! dwarf_haschildren (funcdie))
    return;

  Dwarf_Die child;
  int res = dwarf_child (funcdie, &child);
  if (res < 0)
    error (EXIT_FAILURE, 0, "dwarf_child: %s", dwarf_errmsg (-1));

  /* We thought there was a child, but the child list was actually
     empty. This isn't technically an error in the DWARF, but it is
     certainly non-optimimal.  */
  if (res == 1)
    return;

  do
    {
      int tag = dwarf_tag (&child);
      if (tag == DW_TAG_variable || tag == DW_TAG_formal_parameter)
	{
	  const char *what = tag == DW_TAG_variable ? "variable" : "parameter";
	  print_die (&child, what, 2);

	  if (dwarf_hasattr (&child, DW_AT_location))
	    {
	      Dwarf_Attribute attr;
	      if (dwarf_attr (&child, DW_AT_location, &attr) == NULL)
		error (EXIT_FAILURE, 0, "dwarf_attr: %s", dwarf_errmsg (-1));

	      Dwarf_Op *expr;
	      size_t exprlen;
	      if (dwarf_getlocation (&attr, &expr, &exprlen) == 0)
		{
		  // Covers all ranges of the function.
		  // Evaluate the expression block for each range.
		  ptrdiff_t offset = 0;
		  Dwarf_Addr base, begin, end;
		  do
		    {
		      offset = dwarf_ranges (funcdie, offset, &base,
					     &begin, &end);
		      if (offset < 0)
			error (EXIT_FAILURE, 0, "dwarf_ranges: %s",
			       dwarf_errmsg (-1));

		      if (offset > 0)
			{
			  if (exprlen == 0)
			    printf ("      (%"
				    PRIx64 ",%" PRIx64
				    ") <empty expression>\n", begin, end);
			  else
			    print_expr_block_addrs (&attr, begin, end,
						    expr, exprlen);
			}
		    }
		  while (offset > 0);

		  if (offset < 0)
		    error (EXIT_FAILURE, 0, "dwarf_ranges: %s",
			   dwarf_errmsg (-1));
		}
	      else
		{
		  Dwarf_Addr base, begin, end;
		  ptrdiff_t offset = 0;
		  while ((offset = dwarf_getlocations (&attr, offset,
						       &base, &begin, &end,
						       &expr, &exprlen)) > 0)
		    if (begin >= end)
		      printf ("      (%" PRIx64 ",%" PRIx64
			      ") <empty range>\n", begin, end); // XXX report?
		    else
		      {
			print_expr_block_addrs (&attr, begin, end,
						expr, exprlen);

			// Extra sanity check for dwarf_getlocation_addr
			// Must at least find one range for begin and end-1.
			Dwarf_Op *expraddr;
			size_t expraddr_len;
			int locs = dwarf_getlocation_addr (&attr, begin,
							   &expraddr,
							   &expraddr_len, 1);
			assert (locs == 1);
			locs = dwarf_getlocation_addr (&attr, end - 1,
						       &expraddr,
						       &expraddr_len, 1);
			assert (locs == 1);
		      }

		  if (offset < 0)
		    error (EXIT_FAILURE, 0, "dwarf_getlocations: %s",
			   dwarf_errmsg (-1));
		}
	    }
	  else if (dwarf_hasattr (&child, DW_AT_const_value))
	    {
	      printf ("      <constant value>\n"); // Lookup type and print.
	    }
	  else
	    {
	      printf ("      <no value>\n");
	    }
	}
    }
  while (dwarf_siblingof (&child, &child) == 0);
}