Esempio n. 1
0
int
main (int argc, char *argv[])
{
  assert (argc >= 3);
  const char *name = argv[1];
  ptrdiff_t cuoff = strtol (argv[2], NULL, 0);
  bool new_style = argc > 3;

  int fd = open (name, O_RDONLY);
  Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);

  Dwarf_Die cudie_mem, *cudie = dwarf_offdie (dbg, cuoff, &cudie_mem);

  for (ptrdiff_t off = new_style ? DWARF_GETMACROS_START : 0;
       (off = dwarf_getmacros (cudie, mac, dbg, off)); )
    if (off == -1)
      {
	puts (dwarf_errmsg (dwarf_errno ()));
	break;
      }

  dwarf_end (dbg);

  return 0;
}
Esempio n. 2
0
/**
 * Tries to read DWARF info from the location given by path, and
 * attach it to the given bin_info instance if it exists.
 *
 * @param bin	bin_info instance for which to set DWARF info
 * @param path	Presumed location of the DWARF info
 * @returns	0 on success, negative value on failure
 */
static
int bin_info_set_dwarf_info_from_path(struct bin_info *bin, char *path)
{
	int fd = -1, ret = 0;
	struct bt_dwarf_cu *cu = NULL;
	Dwarf *dwarf_info = NULL;

	if (!bin || !path) {
		goto error;
	}

	fd = open(path, O_RDONLY);
	if (fd < 0) {
		fd = -errno;
		goto error;
	}

	dwarf_info = dwarf_begin(fd, DWARF_C_READ);
	if (!dwarf_info) {
		goto error;
	}

	/*
	 * Check if the dwarf info has any CU. If not, the
	 * executable's object file contains no DWARF info.
	 */
	cu = bt_dwarf_cu_create(dwarf_info);
	if (!cu) {
		goto error;
	}

	ret = bt_dwarf_cu_next(cu);
	if (ret) {
		goto error;
	}

	bin->dwarf_fd = fd;
	bin->dwarf_path = strdup(path);
	if (!bin->dwarf_path) {
		goto error;
	}
	bin->dwarf_info = dwarf_info;
	free(cu);

	return 0;

error:
	if (fd >= 0) {
		close(fd);
		fd = -1;
	}
	dwarf_end(dwarf_info);
	g_free(dwarf_info);
	free(cu);

	return fd;
}
int
main (int argc, char *argv[])
{
 int cnt;

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

      printf ("file: %s\n", basename (argv[cnt]));

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

      Dwarf_Off off = 0;
      Dwarf_Off old_off = 0;
      size_t hsize;
      Dwarf_Off abbrev;
      uint8_t addresssize;
      uint8_t offsetsize;
      while (dwarf_nextcu (dbg, off, &off, &hsize, &abbrev, &addresssize,
			   &offsetsize) == 0)
	{
	  printf ("New CU: off = %llu, hsize = %zu, ab = %llu, as = %" PRIu8
		  ", os = %" PRIu8 "\n",
		  (unsigned long long int) old_off, hsize,
		  (unsigned long long int) abbrev, addresssize,
		  offsetsize);

	  Dwarf_Die die;
	  if (dwarf_offdie (dbg, old_off + hsize, &die) != NULL)
	    handle (dbg, &die, 1);

	  old_off = off;
	}

      dwarf_end (dbg);
      close (fd);
    }

  return 0;
}
Esempio n. 4
0
BT_HIDDEN
void bin_info_destroy(struct bin_info *bin)
{
	if (!bin) {
		return;
	}

	dwarf_end(bin->dwarf_info);

	free(bin->debug_info_dir);
	free(bin->elf_path);
	free(bin->dwarf_path);
	g_free(bin->build_id);
	free(bin->dbg_link_filename);

	elf_end(bin->elf_file);

	close(bin->elf_fd);
	close(bin->dwarf_fd);

	g_free(bin);
}
int
main (int argc, char **argv)
{
  assert (argc > 1);

  int i = open (argv[1], O_RDONLY);
  assert (i >= 0);

  Dwarf *dw = dwarf_begin (i, DWARF_C_READ);
  assert (dw != NULL);

  Dwarf_Die die_mem, *die;
  die = dwarf_offdie (dw, 11, &die_mem);
  assert (die == &die_mem);
  assert (dwarf_tag (die) == 0);

  die = dwarf_offdie (dw, 11, &die_mem);
  assert (die == &die_mem);
  assert (dwarf_tag (die) == 0);

  dwarf_end (dw);
  return 0;
}
Esempio n. 6
0
int
main (int argc, char *argv[])
{
  for (int i = 1; i < argc; ++i)
    {
      int fd = open (argv[i], O_RDONLY);

      Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
      if (dbg != NULL)
	{
	  Dwarf_Off off = 0;
	  size_t cuhl;
	  Dwarf_Off noff;

	  while (dwarf_nextcu (dbg, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
	    {
	      Dwarf_Die die_mem;
	      Dwarf_Die *die = dwarf_offdie (dbg, off + cuhl, &die_mem);

	      Dwarf_Die iter_mem;
	      Dwarf_Die *iter = &iter_mem;
	      dwarf_child (die, &iter_mem);

	      while (1)
		{
		  if (dwarf_tag (iter) == DW_TAG_variable)
		    {
		      Dwarf_Attribute attr_mem;
		      Dwarf_Die form_mem;
		      dwarf_formref_die (dwarf_attr (iter, DW_AT_type,
						     &attr_mem),
					 &form_mem);
		    }

		  if (dwarf_siblingof (iter, &iter_mem) != 0)
		    break;
		}

	      off = noff;
	    }

	  off = 0;
	  uint64_t type_sig;

	  while (dwarf_next_unit (dbg, off, &noff, &cuhl, NULL, NULL, NULL,
				  NULL, &type_sig, NULL) == 0)
	    {
	      Dwarf_Die die_mem;
	      Dwarf_Die *die = dwarf_offdie_types (dbg, off + cuhl, &die_mem);

	      if (die == NULL)
		printf ("fail\n");
	      else
		printf ("ok\n");

	      off = noff;
	    }

	  dwarf_end (dbg);
	}

      close (fd);
    }
}
Esempio n. 7
0
int
main(int argc, char **argv)
{
	Dwarf_Off off, lastoff;
	Dwarf *dw;

	size_t hdr_size;
	int cufd, error;

	argv0 = argv[0];
	if (argc < 3)
		usage();

	structname = argv[1];
	binary = argv[2];

	elf_version(EV_CURRENT);

	cufd = open(binary, O_RDONLY);
	if (cufd == -1)
		err(EX_USAGE, "open");

	dw = dwarf_begin(cufd, DWARF_C_READ);
	if (dw == NULL) {
		error = dwarf_errno();
		if (error == DWARF_E_NO_REGFILE)
			errx(EX_USAGE, "%s: Not a regular file", binary);
		dwarf_err_errno(EX_DATAERR, error, "dwarf_begin");
	}

	get_elf_pointer_size(dw);

	/* XXX worry about .debug_types sections later. */

	lastoff = off = 0;
	while (dwarf_nextcu(dw, off, &off, &hdr_size, NULL, NULL, NULL) == 0) {
		Dwarf_Die cu_die, die;
		int x;

		if (dwarf_offdie(dw, lastoff + hdr_size, &cu_die) == NULL)
			continue;
		lastoff = off;

		/*
		 * A CU may be empty because e.g. an empty (or fully #if0'd)
		 * file is compiled.
		 */
		if (dwarf_child(&cu_die, &die))
			continue;

		/* Loop through all DIEs in the CU. */
		do {
			if (isstruct(dwarf_tag(&die)) &&
			    dwarf_haschildren(&die) &&
			    dwarf_diename(&die) &&
			    strcmp(dwarf_diename(&die), structname) == 0) {
				structprobe(dw, &die);
				goto out;
			}

		} while ((x = dwarf_siblingof(&die, &die)) == 0);
		if (x == -1)
			dwarf_err(EX_DATAERR, "dwarf_siblingof");
	}

out:
	if (dwarf_end(dw))
		dwarf_err(EX_SOFTWARE, "dwarf_end");

	return (EX_OK);
}
Esempio n. 8
0
/* Search function from function name */
static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
{
	struct dwarf_callback_param *param = data;
	struct probe_finder *pf = param->data;
	struct perf_probe_point *pp = &pf->pev->point;

	/* Check tag and diename */
	if (dwarf_tag(sp_die) != DW_TAG_subprogram ||
	    die_compare_name(sp_die, pp->function) != 0)
		return DWARF_CB_OK;

	pf->fname = dwarf_decl_file(sp_die);
	if (pp->line) { /* Function relative line */
		dwarf_decl_line(sp_die, &pf->lno);
		pf->lno += pp->line;
		param->retval = find_probe_point_by_line(pf);
	} else if (!dwarf_func_inline(sp_die)) {
		/* Real function */
		if (pp->lazy_line)
			param->retval = find_probe_point_lazy(sp_die, pf);
		else {
			if (dwarf_entrypc(sp_die, &pf->addr) != 0) {
				pr_warning("Failed to get entry pc of %s.\n",
					   dwarf_diename(sp_die));
				param->retval = -ENOENT;
				return DWARF_CB_ABORT;
			}
			pf->addr += pp->offset;
			/* TODO: Check the address in this function */
			param->retval = convert_probe_point(sp_die, pf);
		}
	} else {
		struct dwarf_callback_param _param = {.data = (void *)pf,
						      .retval = 0};
		/* Inlined function: search instances */
		dwarf_func_inline_instances(sp_die, probe_point_inline_cb,
					    &_param);
		param->retval = _param.retval;
	}

	return DWARF_CB_ABORT; /* Exit; no same symbol in this CU. */
}

static int find_probe_point_by_func(struct probe_finder *pf)
{
	struct dwarf_callback_param _param = {.data = (void *)pf,
					      .retval = 0};
	dwarf_getfuncs(&pf->cu_die, probe_point_search_cb, &_param, 0);
	return _param.retval;
}

/* Find kprobe_trace_events specified by perf_probe_event from debuginfo */
int find_kprobe_trace_events(int fd, struct perf_probe_event *pev,
			     struct kprobe_trace_event **tevs, int max_tevs)
{
	struct probe_finder pf = {.pev = pev, .max_tevs = max_tevs};
	struct perf_probe_point *pp = &pev->point;
	Dwarf_Off off, noff;
	size_t cuhl;
	Dwarf_Die *diep;
	Dwarf *dbg;
	int ret = 0;

	pf.tevs = zalloc(sizeof(struct kprobe_trace_event) * max_tevs);
	if (pf.tevs == NULL)
		return -ENOMEM;
	*tevs = pf.tevs;
	pf.ntevs = 0;

	dbg = dwarf_begin(fd, DWARF_C_READ);
	if (!dbg) {
		pr_warning("No dwarf info found in the vmlinux - "
			"please rebuild with CONFIG_DEBUG_INFO=y.\n");
		free(pf.tevs);
		*tevs = NULL;
		return -EBADF;
	}

#if _ELFUTILS_PREREQ(0, 142)
	/* Get the call frame information from this dwarf */
	pf.cfi = dwarf_getcfi(dbg);
#endif

	off = 0;
	line_list__init(&pf.lcache);
	/* Loop on CUs (Compilation Unit) */
	while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) &&
	       ret >= 0) {
		/* Get the DIE(Debugging Information Entry) of this CU */
		diep = dwarf_offdie(dbg, off + cuhl, &pf.cu_die);
		if (!diep)
			continue;

		/* Check if target file is included. */
		if (pp->file)
			pf.fname = cu_find_realpath(&pf.cu_die, pp->file);
		else
			pf.fname = NULL;

		if (!pp->file || pf.fname) {
			if (pp->function)
				ret = find_probe_point_by_func(&pf);
			else if (pp->lazy_line)
				ret = find_probe_point_lazy(NULL, &pf);
			else {
				pf.lno = pp->line;
				ret = find_probe_point_by_line(&pf);
			}
		}
		off = noff;
	}
	line_list__free(&pf.lcache);
	dwarf_end(dbg);

	return (ret < 0) ? ret : pf.ntevs;
}

/* Reverse search */
int find_perf_probe_point(int fd, unsigned long addr,
			  struct perf_probe_point *ppt)
{
	Dwarf_Die cudie, spdie, indie;
	Dwarf *dbg;
	Dwarf_Line *line;
	Dwarf_Addr laddr, eaddr;
	const char *tmp;
	int lineno, ret = 0;
	bool found = false;

	dbg = dwarf_begin(fd, DWARF_C_READ);
	if (!dbg)
		return -EBADF;

	/* Find cu die */
	if (!dwarf_addrdie(dbg, (Dwarf_Addr)addr, &cudie)) {
		ret = -EINVAL;
		goto end;
	}

	/* Find a corresponding line */
	line = dwarf_getsrc_die(&cudie, (Dwarf_Addr)addr);
	if (line) {
		if (dwarf_lineaddr(line, &laddr) == 0 &&
		    (Dwarf_Addr)addr == laddr &&
		    dwarf_lineno(line, &lineno) == 0) {
			tmp = dwarf_linesrc(line, NULL, NULL);
			if (tmp) {
				ppt->line = lineno;
				ppt->file = strdup(tmp);
				if (ppt->file == NULL) {
					ret = -ENOMEM;
					goto end;
				}
				found = true;
			}
		}
	}

	/* Find a corresponding function */
	if (die_find_real_subprogram(&cudie, (Dwarf_Addr)addr, &spdie)) {
		tmp = dwarf_diename(&spdie);
		if (!tmp || dwarf_entrypc(&spdie, &eaddr) != 0)
			goto end;

		if (ppt->line) {
			if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr,
						&indie)) {
				/* addr in an inline function */
				tmp = dwarf_diename(&indie);
				if (!tmp)
					goto end;
				ret = dwarf_decl_line(&indie, &lineno);
			} else {
				if (eaddr == addr) {	/* Function entry */
					lineno = ppt->line;
					ret = 0;
				} else
					ret = dwarf_decl_line(&spdie, &lineno);
			}
			if (ret == 0) {
				/* Make a relative line number */
				ppt->line -= lineno;
				goto found;
			}
		}
		/* We don't have a line number, let's use offset */
		ppt->offset = addr - (unsigned long)eaddr;
found:
		ppt->function = strdup(tmp);
		if (ppt->function == NULL) {
			ret = -ENOMEM;
			goto end;
		}
		found = true;
	}

end:
	dwarf_end(dbg);
	if (ret >= 0)
		ret = found ? 1 : 0;
	return ret;
}

/* Add a line and store the src path */
static int line_range_add_line(const char *src, unsigned int lineno,
			       struct line_range *lr)
{
	/* Copy real path */
	if (!lr->path) {
		lr->path = strdup(src);
		if (lr->path == NULL)
			return -ENOMEM;
	}
	return line_list__add_line(&lr->line_list, lineno);
}

/* Search function declaration lines */
static int line_range_funcdecl_cb(Dwarf_Die *sp_die, void *data)
{
	struct dwarf_callback_param *param = data;
	struct line_finder *lf = param->data;
	const char *src;
	int lineno;

	src = dwarf_decl_file(sp_die);
	if (src && strtailcmp(src, lf->fname) != 0)
		return DWARF_CB_OK;

	if (dwarf_decl_line(sp_die, &lineno) != 0 ||
	    (lf->lno_s > lineno || lf->lno_e < lineno))
		return DWARF_CB_OK;

	param->retval = line_range_add_line(src, lineno, lf->lr);
	if (param->retval < 0)
		return DWARF_CB_ABORT;
	return DWARF_CB_OK;
}

static int find_line_range_func_decl_lines(struct line_finder *lf)
{
	struct dwarf_callback_param param = {.data = (void *)lf, .retval = 0};
	dwarf_getfuncs(&lf->cu_die, line_range_funcdecl_cb, &param, 0);
	return param.retval;
}

/* Find line range from its line number */
static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
{
	Dwarf_Lines *lines;
	Dwarf_Line *line;
	size_t nlines, i;
	Dwarf_Addr addr;
	int lineno, ret = 0;
	const char *src;
	Dwarf_Die die_mem;

	line_list__init(&lf->lr->line_list);
	if (dwarf_getsrclines(&lf->cu_die, &lines, &nlines) != 0) {
		pr_warning("No source lines found in this CU.\n");
		return -ENOENT;
	}

	/* Search probable lines on lines list */
	for (i = 0; i < nlines; i++) {
		line = dwarf_onesrcline(lines, i);
		if (dwarf_lineno(line, &lineno) != 0 ||
		    (lf->lno_s > lineno || lf->lno_e < lineno))
			continue;

		if (sp_die) {
			/* Address filtering 1: does sp_die include addr? */
			if (dwarf_lineaddr(line, &addr) != 0 ||
			    !dwarf_haspc(sp_die, addr))
				continue;

			/* Address filtering 2: No child include addr? */
			if (die_find_inlinefunc(sp_die, addr, &die_mem))
				continue;
		}

		/* TODO: Get fileno from line, but how? */
		src = dwarf_linesrc(line, NULL, NULL);
		if (strtailcmp(src, lf->fname) != 0)
			continue;

		ret = line_range_add_line(src, lineno, lf->lr);
		if (ret < 0)
			return ret;
	}

	/*
	 * Dwarf lines doesn't include function declarations. We have to
	 * check functions list or given function.
	 */
	if (sp_die) {
		src = dwarf_decl_file(sp_die);
		if (src && dwarf_decl_line(sp_die, &lineno) == 0 &&
		    (lf->lno_s <= lineno && lf->lno_e >= lineno))
			ret = line_range_add_line(src, lineno, lf->lr);
	} else
		ret = find_line_range_func_decl_lines(lf);

	/* Update status */
	if (ret >= 0)
		if (!list_empty(&lf->lr->line_list))
			ret = lf->found = 1;
		else
			ret = 0;	/* Lines are not found */
	else {
		free(lf->lr->path);
		lf->lr->path = NULL;
	}
	return ret;
}

static int line_range_inline_cb(Dwarf_Die *in_die, void *data)
{
	struct dwarf_callback_param *param = data;

	param->retval = find_line_range_by_line(in_die, param->data);
	return DWARF_CB_ABORT;	/* No need to find other instances */
}

/* Search function from function name */
static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
{
	struct dwarf_callback_param *param = data;
	struct line_finder *lf = param->data;
	struct line_range *lr = lf->lr;

	if (dwarf_tag(sp_die) == DW_TAG_subprogram &&
	    die_compare_name(sp_die, lr->function) == 0) {
		lf->fname = dwarf_decl_file(sp_die);
		dwarf_decl_line(sp_die, &lr->offset);
		pr_debug("fname: %s, lineno:%d\n", lf->fname, lr->offset);
		lf->lno_s = lr->offset + lr->start;
		if (lf->lno_s < 0)	/* Overflow */
			lf->lno_s = INT_MAX;
		lf->lno_e = lr->offset + lr->end;
		if (lf->lno_e < 0)	/* Overflow */
			lf->lno_e = INT_MAX;
		pr_debug("New line range: %d to %d\n", lf->lno_s, lf->lno_e);
		lr->start = lf->lno_s;
		lr->end = lf->lno_e;
		if (dwarf_func_inline(sp_die)) {
			struct dwarf_callback_param _param;
			_param.data = (void *)lf;
			_param.retval = 0;
			dwarf_func_inline_instances(sp_die,
						    line_range_inline_cb,
						    &_param);
			param->retval = _param.retval;
		} else
			param->retval = find_line_range_by_line(sp_die, lf);
		return DWARF_CB_ABORT;
	}
	return DWARF_CB_OK;
}

static int find_line_range_by_func(struct line_finder *lf)
{
	struct dwarf_callback_param param = {.data = (void *)lf, .retval = 0};
	dwarf_getfuncs(&lf->cu_die, line_range_search_cb, &param, 0);
	return param.retval;
}

int find_line_range(int fd, struct line_range *lr)
{
	struct line_finder lf = {.lr = lr, .found = 0};
	int ret = 0;
	Dwarf_Off off = 0, noff;
	size_t cuhl;
	Dwarf_Die *diep;
	Dwarf *dbg;

	dbg = dwarf_begin(fd, DWARF_C_READ);
	if (!dbg) {
		pr_warning("No dwarf info found in the vmlinux - "
			"please rebuild with CONFIG_DEBUG_INFO=y.\n");
		return -EBADF;
	}

	/* Loop on CUs (Compilation Unit) */
	while (!lf.found && ret >= 0) {
		if (dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) != 0)
			break;

		/* Get the DIE(Debugging Information Entry) of this CU */
		diep = dwarf_offdie(dbg, off + cuhl, &lf.cu_die);
		if (!diep)
			continue;

		/* Check if target file is included. */
		if (lr->file)
			lf.fname = cu_find_realpath(&lf.cu_die, lr->file);
		else
			lf.fname = 0;

		if (!lr->file || lf.fname) {
			if (lr->function)
				ret = find_line_range_by_func(&lf);
			else {
				lf.lno_s = lr->start;
				lf.lno_e = lr->end;
				ret = find_line_range_by_line(NULL, &lf);
			}
		}
		off = noff;
	}
	pr_debug("path: %lx\n", (unsigned long)lr->path);
	dwarf_end(dbg);

	return (ret < 0) ? ret : lf.found;
}
Esempio n. 9
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;
}
Esempio n. 10
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;
	  close (fd);
	  continue;
	}

      Dwarf_Aranges *aranges;
      size_t naranges;
      if (dwarf_getaranges (dbg, &aranges, &naranges) != 0)
	printf ("%s: cannot get aranges\n", argv[cnt]);
      else
	{
	  for (size_t i = 0; i < ntestaddr; ++i)
	    {
	      Dwarf_Arange *found;

	      found = dwarf_getarange_addr (aranges, testaddr[i]);
	      if (found != NULL)
		{
		  Dwarf_Off cu_offset;

		  if (dwarf_getarangeinfo (found, NULL, NULL, &cu_offset) != 0)
		    {
		      puts ("failed to get CU die offset");
		      result = 1;
		    }
		  else
		    {
		      const char *cuname;
		      Dwarf_Die cu_die;

		      if (dwarf_offdie (dbg, cu_offset, &cu_die) == NULL
			  || (cuname = dwarf_diename (&cu_die)) == NULL)
			{
			  puts ("failed to get CU die");
			  result = 1;
			}
		      else
			printf ("CU name: \"%s\"\n", cuname);
		    }
		}
	      else
		printf ("%#llx: not in range\n",
			(unsigned long long int) testaddr[i]);
	    }

	  for (size_t i = 0; i < naranges; ++i)
	    {
	      Dwarf_Arange *arange = dwarf_onearange (aranges, i);
	      if (arange == NULL)
		{
		  printf ("cannot get arange %zu: %s\n", i, dwarf_errmsg (-1));
		  break;
		}

	      Dwarf_Addr start;
	      Dwarf_Word length;
	      Dwarf_Off cu_offset;

	      if (dwarf_getarangeinfo (arange, &start, &length, &cu_offset)
		  != 0)
		{
		  printf ("cannot get info from aranges[%zu]\n", i);
		  result = 1;
		}
	      else
		{
		  printf (" [%2zu] start: %#llx, length: %llu, cu: %llu\n",
			  i, (unsigned long long int) start,
			  (unsigned long long int) length,
			  (unsigned long long int) cu_offset);

		  const char *cuname;
		  Dwarf_Die cu_die;
		  if (dwarf_offdie (dbg, cu_offset, &cu_die) == NULL
		      || (cuname = dwarf_diename (&cu_die)) == NULL)
		    {
		      puts ("failed to get CU die");
		      result = 1;
		    }
		  else
		    printf ("CU name: \"%s\"\n", cuname);
		}
	    }
	}

      dwarf_end (dbg);
      close (fd);
    }

  return result;
}
Esempio n. 11
0
int
main (int argc, char *argv[])
{
  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: %s\n", argv[cnt], dwarf_errmsg (-1));
	  close  (fd);
	  continue;
	}

      Dwarf_Off cuoff = 0;
      Dwarf_Off old_cuoff = 0;
      size_t hsize;
      while (dwarf_nextcu (dbg, cuoff, &cuoff, &hsize, NULL, NULL, NULL) == 0)
	{
	  /* Get the DIE for the CU.  */
	  Dwarf_Die die;
 	  if (dwarf_offdie (dbg, old_cuoff + hsize, &die) == NULL)
	    /* Something went wrong.  */
	    break;

	  Dwarf_Off offset = 0;

	  while (1)
	    {
	      size_t length;
	      Dwarf_Abbrev *abbrev = dwarf_getabbrev (&die, offset, &length);
	      if (abbrev == NULL || abbrev == DWARF_END_ABBREV)
		/* End of the list.  */
		break;

	      unsigned tag = dwarf_getabbrevtag (abbrev);
	      if (tag == 0)
		{
		  printf ("dwarf_getabbrevtag at offset %llu returned error: %s\n",
			  (unsigned long long int) offset,
			  dwarf_errmsg (-1));
		  break;
		}

	      unsigned code = dwarf_getabbrevcode (abbrev);
	      if (code == 0)
		{
		  printf ("dwarf_getabbrevcode at offset %llu returned error: %s\n",
			  (unsigned long long int) offset,
			  dwarf_errmsg (-1));
		  break;
		}

	      int children = dwarf_abbrevhaschildren (abbrev);
	      if (children < 0)
		{
		  printf ("dwarf_abbrevhaschildren at offset %llu returned error: %s\n",
			  (unsigned long long int) offset,
			  dwarf_errmsg (-1));
		  break;
		}

	      printf ("abbrev[%llu]: code = %u, tag = %u, children = %d\n",
		      (unsigned long long int) offset, code, tag, children);

	      size_t attrcnt;
	      if (dwarf_getattrcnt (abbrev, &attrcnt) != 0)
		{
		  printf ("dwarf_getattrcnt at offset %llu returned error: %s\n",
			  (unsigned long long int) offset,
			  dwarf_errmsg (-1));
		  break;
		}

	      unsigned int attr_num;
	      unsigned int attr_form;
	      Dwarf_Off aboffset;
	      size_t j;
	      for (j = 0; j < attrcnt; ++j)
		if (dwarf_getabbrevattr (abbrev, j, &attr_num, &attr_form,
					 &aboffset))
		  printf ("dwarf_getabbrevattr for abbrev[%llu] and index %zu failed\n",
			  (unsigned long long int) offset, j);
		else
		  printf ("abbrev[%llu]: attr[%zu]: code = %u, form = %u, offset = %" PRIu64 "\n",
			  (unsigned long long int) offset, j, attr_num,
			  attr_form, (uint64_t) aboffset);

	      offset += length;
	    }

	  old_cuoff = cuoff;
	}

      if (dwarf_end (dbg) != 0)
	printf ("dwarf_end failed for %s: %s\n", argv[cnt],
		dwarf_errmsg (-1));

      close (fd);
    }

  return 0;
}