Пример #1
0
BT_HIDDEN
int bt_dwarf_die_get_call_file(struct bt_dwarf_die *die, char **filename)
{
	int ret;
	Dwarf_Sword file_no;
	const char *_filename = NULL;
	Dwarf_Files *src_files = NULL;
	Dwarf_Attribute *file_attr = NULL;
	struct bt_dwarf_die *cu_die = NULL;

	if (!die || !filename) {
		goto error;
	}

	file_attr = g_new0(Dwarf_Attribute, 1);
	if (!file_attr) {
		goto error;
	}

	file_attr = dwarf_attr(die->dwarf_die, DW_AT_call_file, file_attr);
	if (!file_attr) {
		goto error;
	}

	ret = dwarf_formsdata(file_attr, &file_no);
	if (ret) {
		goto error;
	}

	cu_die = bt_dwarf_die_create(die->cu);
	if (!cu_die) {
		goto error;
	}

	ret = dwarf_getsrcfiles(cu_die->dwarf_die, &src_files, NULL);
	if (ret) {
		goto error;
	}

	_filename = dwarf_filesrc(src_files, file_no, NULL, NULL);
	if (!_filename) {
		goto error;
	}

	*filename = strdup(_filename);

	bt_dwarf_die_destroy(cu_die);
	g_free(file_attr);

	return 0;

error:
	bt_dwarf_die_destroy(cu_die);
	g_free(file_attr);

	return -1;
}
Пример #2
0
/**
 * die_get_call_file - Get callsite file name of inlined function instance
 * @in_die: a DIE of an inlined function instance
 *
 * Get call-site file name of @in_die. This means from which file the inline
 * function is called.
 */
const char *die_get_call_file(Dwarf_Die *in_die)
{
	Dwarf_Die cu_die;
	Dwarf_Files *files;
	int idx;

	idx = die_get_call_fileno(in_die);
	if (idx < 0 || !dwarf_diecu(in_die, &cu_die, NULL, NULL) ||
	    dwarf_getsrcfiles(&cu_die, &files, NULL) != 0)
		return NULL;

	return dwarf_filesrc(files, idx, NULL, NULL);
}
Пример #3
0
/**
 * cu_find_realpath - Find the realpath of the target file
 * @cu_die: A DIE(dwarf information entry) of CU(compilation Unit)
 * @fname:  The tail filename of the target file
 *
 * Find the real(long) path of @fname in @cu_die.
 */
const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname)
{
	Dwarf_Files *files;
	size_t nfiles, i;
	const char *src = NULL;
	int ret;

	if (!fname)
		return NULL;

	ret = dwarf_getsrcfiles(cu_die, &files, &nfiles);
	if (ret != 0)
		return NULL;

	for (i = 0; i < nfiles; i++) {
		src = dwarf_filesrc(files, i, NULL, NULL);
		if (strtailcmp(src, fname) == 0)
			break;
	}
	if (i == nfiles)
		return NULL;
	return src;
}
Пример #4
0
static int
mac (Dwarf_Macro *macro, void *dbg)
{
  static int level = 0;

  unsigned int opcode;
  dwarf_macro_opcode (macro, &opcode);
  switch (opcode)
    {
    case DW_MACRO_GNU_transparent_include:
      {
	Dwarf_Attribute at;
	int r = dwarf_macro_param (macro, 0, &at);
	assert (r == 0);

	Dwarf_Word w;
	r = dwarf_formudata (&at, &w);
	assert (r == 0);

	printf ("%*sinclude %#" PRIx64 "\n", level, "", w);
	++level;
	include (dbg, w, DWARF_GETMACROS_START);
	--level;
	printf ("%*s/include\n", level, "");
	break;
      }

    case DW_MACRO_GNU_start_file:
      {
	Dwarf_Files *files;
	size_t nfiles;
	if (dwarf_macro_getsrcfiles (dbg, macro, &files, &nfiles) < 0)
	  printf ("dwarf_macro_getsrcfiles: %s\n",
		  dwarf_errmsg (dwarf_errno ()));

	Dwarf_Word w = 0;
	dwarf_macro_param2 (macro, &w, NULL);

	const char *name = dwarf_filesrc (files, (size_t) w, NULL, NULL);
	printf ("%*sfile %s\n", level, "", name);
	++level;
	break;
      }

    case DW_MACRO_GNU_end_file:
      {
	--level;
	printf ("%*s/file\n", level, "");
	break;
      }

    case DW_MACINFO_define:
    case DW_MACRO_GNU_define_indirect:
      {
	const char *value;
	dwarf_macro_param2 (macro, NULL, &value);
	printf ("%*s%s\n", level, "", value);
	break;
      }

    case DW_MACINFO_undef:
    case DW_MACRO_GNU_undef_indirect:
      break;

    default:
      {
	size_t paramcnt;
	dwarf_macro_getparamcnt (macro, &paramcnt);
	printf ("%*sopcode %u with %zd arguments\n",
		level, "", opcode, paramcnt);
	break;
      }
    }

  return DWARF_CB_ABORT;
}
Пример #5
0
int
main (int argc, char *argv[])
{
  int result = 0;
  int cnt;

  for (cnt = 1; cnt < argc; ++cnt)
    {
      int fd = open (argv[cnt], O_RDONLY);

      Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
      if (dbg == NULL)
	{
	  printf ("%s not usable\n", argv[cnt]);
	  result = 1;
	  if (fd != -1)
	    close (fd);
	  continue;
	}

      Dwarf_Off o = 0;
      Dwarf_Off ncu;
      Dwarf_Off ao;
      size_t cuhl;
      uint8_t asz;
      uint8_t osz;
      while (dwarf_nextcu (dbg, o, &ncu, &cuhl, &ao, &asz, &osz) == 0)
	{
	  printf ("cuhl = %zu, o = %llu, asz = %hhu, osz = %hhu, ncu = %llu\n",
		  cuhl, (unsigned long long int) ao,
		  asz, osz, (unsigned long long int) ncu);

	  Dwarf_Die die_mem;
	  Dwarf_Die *die = dwarf_offdie (dbg, o + cuhl, &die_mem);
	  if (die == NULL)
	    {
	      printf ("%s: cannot get CU die\n", argv[cnt]);
	      result = 1;
	      break;
	    }

	  Dwarf_Files *files;
	  size_t nfiles;
	  if (dwarf_getsrcfiles (die, &files, &nfiles) != 0)
	    {
	      printf ("%s: cannot get files\n", argv[cnt]);
	      result = 1;
	      break;
	    }

	  for (int i = 0; i < nfiles; ++i)
	    printf (" file[%d] = \"%s\"\n", i,
		    dwarf_filesrc (files, i, NULL, NULL));

	  o = ncu;
	}

      dwarf_end (dbg);
      close (fd);
    }

  return result;
}
Пример #6
0
static int
process_cu (Dwarf_Die *cu_die)
{
  Dwarf_Attribute attr;
  const char *name;
  const char *dir = NULL;
  
  Dwarf_Files *files;
  size_t n;
  int i;
  
  if (dwarf_tag (cu_die) != DW_TAG_compile_unit)
    {
      fprintf (stderr, "DIE isn't a compile unit");
      return -1;
    }
  
  if (dwarf_attr (cu_die, DW_AT_name, &attr) == NULL)
    {
      fprintf(stderr, "CU doesn't have a DW_AT_name");
      return -1;
    }
  
  name = dwarf_formstring (&attr);
  if (name == NULL)
    {
      fprintf(stderr, "Couldn't get DW_AT_name as string, %s",
	     dwarf_errmsg (-1));
      return -1;
    }
  
  if (dwarf_attr (cu_die, DW_AT_comp_dir, &attr) != NULL)
    {
      dir = dwarf_formstring (&attr);
      if (dir == NULL)
	{
	  fprintf(stderr, "Couldn't get DW_AT_comp_die as string, %s",
		 dwarf_errmsg (-1));
	  return -1;
	}
    }
  
  if (dir == NULL)
    printf ("%s\n", name);
  else
    printf ("%s/%s\n", dir, name);
  
  if (dwarf_getsrcfiles (cu_die, &files, &n) != 0)
    {
      fprintf(stderr, "Couldn't get CU file table, %s",
	     dwarf_errmsg (-1));
      return -1;
    }
  
  for (i = 1; i < n; i++)
    {
      const char *file = dwarf_filesrc (files, i, NULL, NULL);
      if (dir != NULL && file[0] != '/')
	printf ("\t%s/%s\n", dir, file);
      else
	printf ("\t%s\n", file);
    }
  
  return 0;
}
Пример #7
0
static void analyze_type(Dwarf_Die *die, struct type *ty)
{
    int ret;
    Dwarf_Attribute at;

    /* find out the values of name, byte_size and type attributes
     * even though not all of them make sense for all tags
     */
    char *name = NULL;
    if (dwarf_attr(die, DW_AT_name, &at) != NULL)
    {
        name = xstrdup(dwarf_formstring(&at));
    }

    struct type sub_type = { .name = NULL, .width = 0 };
    if (dwarf_attr(die, DW_AT_type, &at) != NULL)
    {
        Dwarf_Die sub_die;
        if (dwarf_formref_die(&at, &sub_die) != NULL)
            analyze_type(&sub_die, &sub_type);
    }

    Dwarf_Word width = 0;
    if (dwarf_attr(die, DW_AT_byte_size, &at) != NULL)
    {
        ret = dwarf_formudata(&at, &width);
        fail_if(ret == -1, "dwarf_formudata");
    }

    switch (dwarf_tag(die))
    {
    case DW_TAG_base_type:
        ty->name = name;
        name = NULL;
        ty->width = (unsigned)width;
        /* TODO: what about encoding? */
        break;

    /* type modifiers */
    case DW_TAG_const_type:
        ty->name = xsprintf("const %s", sub_type.name ?: "void");
        ty->width = sub_type.width;
        break;

    case DW_TAG_pointer_type:
        ty->width = (unsigned)width;
        ty->name = xsprintf("%s*", sub_type.name ?: "void");
        break;

    case DW_TAG_restrict_type:
        ty->name = xsprintf("%s restrict", sub_type.name ?: "void");
        ty->width = sub_type.width;
        break;

    case DW_TAG_volatile_type:
        ty->name = xsprintf("volatile %s", sub_type.name ?: "void");
        ty->width = sub_type.width;
        break;

    case DW_TAG_typedef:
        ty->name = name;
        name = NULL;
        ty->width = sub_type.width;
        break;

    case DW_TAG_array_type:
        ty->name = xsprintf("%s[]", sub_type.name);
        ty->width = POINTER_SIZE;
        break;

    case DW_TAG_structure_type:
        if (name)
            ty->name = xsprintf("struct %s", name);
        else
            ty->name = xstrdup("struct");
        ty->width = (unsigned)width;
        break;

    case DW_TAG_union_type:
        if (name)
            ty->name = xsprintf("union %s", name);
        else
            ty->name = xstrdup("union");
        ty->width = (unsigned)width;
        break;

    case DW_TAG_class_type:
        ty->name = xsprintf("class %s", name);
        ty->width = (unsigned)width;
        break;

    case DW_TAG_enumeration_type:
        ty->name = xsprintf("enum %s", name);
        ty->width = (unsigned)width;
        break;

    case DW_TAG_subroutine_type:
        ty->name = xstrdup("FUNCTION");
        ty->width = 0; /* TODO */
        break;

    default:
        warn("Unknown type 0x%x named %s with width %u", dwarf_tag(die), name, (unsigned)width);
        break;
    }

    free(sub_type.name);
    free(name);
}

void analyze_name_location(Dwarf_Die *die, Dwarf_Files *files,
                           char **name, struct location* loc)
{
    int ret;
    Dwarf_Attribute at;
    Dwarf_Word w;

    if (dwarf_attr_integrate(die, DW_AT_name, &at) != NULL)
    {
        *name = xstrdup(dwarf_formstring(&at));
    }

    if (dwarf_attr_integrate(die, DW_AT_decl_file, &at) != NULL)
    {
        ret = dwarf_formudata(&at, &w);
        fail_if(ret == -1, "dwarf_formudata");
        loc->file = xstrdup(dwarf_filesrc(files, (size_t)w, NULL, NULL));
    }

    if (dwarf_attr_integrate(die, DW_AT_decl_line, &at) != NULL)
    {
        ret = dwarf_formudata(&at, &w);
        fail_if(ret == -1, "dwarf_formudata");
        loc->line = (unsigned)w;
    }
}