From: Namhyung Kim <namhyung@kernel.org>
To: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>,
Paul Mackerras <paulus@samba.org>, Ingo Molnar <mingo@kernel.org>,
Namhyung Kim <namhyung.kim@lge.com>,
LKML <linux-kernel@vger.kernel.org>, Jiri Olsa <jolsa@redhat.com>,
Roberto Vitillo <ravitillo@lbl.gov>
Subject: [PATCH 8/9] perf tools: Implement addr2line directly using libbfd
Date: Wed, 11 Sep 2013 14:09:32 +0900 [thread overview]
Message-ID: <1378876173-13363-9-git-send-email-namhyung@kernel.org> (raw)
In-Reply-To: <1378876173-13363-1-git-send-email-namhyung@kernel.org>
From: Roberto Vitillo <ravitillo@lbl.gov>
When the srcline sort key is used , the external addr2line utility
needs to be run for each hist entry to get the srcline info. This can
consume quite a time if one has a huge perf.data file.
So rather than executing the external utility, implement it internally
and just call it. We can do it since we've linked with libbfd
already.
Reviewed-by: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Roberto Agostino Vitillo <ravitillo@lbl.gov>
[namhyung@kernel.org: Use a2l_data struct instead of static globals]
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
tools/perf/config/Makefile | 4 ++
tools/perf/util/srcline.c | 167 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 171 insertions(+)
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 214e17e97e5c..128d580ca397 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -396,6 +396,10 @@ else
endif
endif
+ifndef ($(filter -lbfd,$(EXTLIBS)),)
+ CFLAGS += -DLIBBFD_SUPPORT
+endif
+
ifndef NO_STRLCPY
ifeq ($(call try-cc,$(SOURCE_STRLCPY),,-DHAVE_STRLCPY),y)
CFLAGS += -DHAVE_STRLCPY
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
index dcff10bed7da..10983a92bb5e 100644
--- a/tools/perf/util/srcline.c
+++ b/tools/perf/util/srcline.c
@@ -8,6 +8,172 @@
#include "util/util.h"
#include "util/debug.h"
+#ifdef LIBBFD_SUPPORT
+
+/*
+ * Implement addr2line using libbfd.
+ */
+#define PACKAGE "perf"
+#include <bfd.h>
+
+struct a2l_data {
+ const char *input;
+ unsigned long addr;
+
+ bool found;
+ const char *filename;
+ const char *funcname;
+ unsigned line;
+
+ bfd *abfd;
+ asymbol **syms;
+};
+
+static int bfd_error(const char *string)
+{
+ const char *errmsg;
+
+ errmsg = bfd_errmsg(bfd_get_error());
+ fflush(stdout);
+
+ if (string)
+ pr_debug("%s: %s\n", string, errmsg);
+ else
+ pr_debug("%s\n", errmsg);
+
+ return -1;
+}
+
+static int slurp_symtab(bfd *abfd, struct a2l_data *a2l)
+{
+ long storage;
+ long symcount;
+ asymbol **syms;
+ bfd_boolean dynamic = FALSE;
+
+ if ((bfd_get_file_flags(abfd) & HAS_SYMS) == 0)
+ return bfd_error(bfd_get_filename(abfd));
+
+ storage = bfd_get_symtab_upper_bound(abfd);
+ if (storage == 0L) {
+ storage = bfd_get_dynamic_symtab_upper_bound(abfd);
+ dynamic = TRUE;
+ }
+ if (storage < 0L)
+ return bfd_error(bfd_get_filename(abfd));
+
+ syms = malloc(storage);
+ if (dynamic)
+ symcount = bfd_canonicalize_dynamic_symtab(abfd, syms);
+ else
+ symcount = bfd_canonicalize_symtab(abfd, syms);
+
+ if (symcount < 0) {
+ free(syms);
+ return bfd_error(bfd_get_filename(abfd));
+ }
+
+ a2l->syms = syms;
+ return 0;
+}
+
+static void find_address_in_section(bfd *abfd, asection *section, void *data)
+{
+ bfd_vma pc, vma;
+ bfd_size_type size;
+ struct a2l_data *a2l = data;
+
+ if (a2l->found)
+ return;
+
+ if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0)
+ return;
+
+ pc = a2l->addr;
+ vma = bfd_get_section_vma(abfd, section);
+ size = bfd_get_section_size(section);
+
+ if (pc < vma || pc >= vma + size)
+ return;
+
+ a2l->found = bfd_find_nearest_line(abfd, section, a2l->syms, pc - vma,
+ &a2l->filename, &a2l->funcname,
+ &a2l->line);
+}
+
+static struct a2l_data *addr2line_init(const char *path)
+{
+ bfd *abfd;
+ struct a2l_data *a2l = NULL;
+
+ abfd = bfd_openr(path, NULL);
+ if (abfd == NULL)
+ return NULL;
+
+ if (!bfd_check_format(abfd, bfd_object))
+ goto out;
+
+ a2l = zalloc(sizeof(*a2l));
+ if (a2l == NULL)
+ goto out;
+
+ a2l->abfd = abfd;
+ a2l->input = strdup(path);
+ if (a2l->input == NULL)
+ goto out;
+
+ if (slurp_symtab(abfd, a2l))
+ goto out;
+
+ return a2l;
+
+out:
+ if (a2l) {
+ free((void *)a2l->input);
+ free(a2l);
+ }
+ bfd_close(abfd);
+ return NULL;
+}
+
+static void addr2line_cleanup(struct a2l_data *a2l)
+{
+ if (a2l->abfd)
+ bfd_close(a2l->abfd);
+ free((void *)a2l->input);
+ free(a2l->syms);
+ free(a2l);
+}
+
+static int addr2line(const char *dso_name, unsigned long addr,
+ char **file, unsigned int *line)
+{
+ int ret = 0;
+ struct a2l_data *a2l;
+
+ a2l = addr2line_init(dso_name);
+ if (a2l == NULL) {
+ pr_warning("addr2line_init failed for %s\n", dso_name);
+ return 0;
+ }
+
+ a2l->addr = addr;
+ bfd_map_over_sections(a2l->abfd, find_address_in_section, a2l);
+
+ if (a2l->found && a2l->filename) {
+ *file = strdup(a2l->filename);
+ *line = a2l->line;
+
+ if (*file)
+ ret = 1;
+ }
+
+ addr2line_cleanup(a2l);
+ return ret;
+}
+
+#else /* LIBBFD_SUPPORT */
+
static int addr2line(const char *dso_name, unsigned long addr,
char **file, unsigned int *line_nr)
{
@@ -53,6 +219,7 @@ out:
pclose(fp);
return ret;
}
+#endif /* LIBBFD_SUPPORT */
char *get_srcline(struct dso *dso, unsigned long addr)
{
--
1.7.11.7
next prev parent reply other threads:[~2013-09-11 5:09 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-09-11 5:09 [PATCHSET 0/9] perf tools: Enhance and correct srcline behavior (v2) Namhyung Kim
2013-09-11 5:09 ` [PATCH 1/9] perf sort: Fix a memory leak on srcline Namhyung Kim
2013-10-15 5:25 ` [tip:perf/core] " tip-bot for Namhyung Kim
2013-09-11 5:09 ` [PATCH 2/9] perf annotate: Reuse path from the result of addr2line Namhyung Kim
2013-10-15 5:25 ` [tip:perf/core] " tip-bot for Namhyung Kim
2013-09-11 5:09 ` [PATCH 3/9] perf hists: Free srcline when freeing hist_entry Namhyung Kim
2013-10-15 5:26 ` [tip:perf/core] " tip-bot for Namhyung Kim
2013-09-11 5:09 ` [PATCH 4/9] perf tools: Factor out get/free_srcline() Namhyung Kim
2013-10-15 5:26 ` [tip:perf/core] perf annotate: " tip-bot for Namhyung Kim
2013-09-11 5:09 ` [PATCH 5/9] perf tools: Do not try to call addr2line for non-binary files Namhyung Kim
2013-10-15 5:26 ` [tip:perf/core] perf tools: Do not try to call addr2line on " tip-bot for Namhyung Kim
2013-09-11 5:09 ` [PATCH 6/9] perf tools: Pass dso instead of dso_name to get_srcline() Namhyung Kim
2013-10-15 5:26 ` [tip:perf/core] perf annotate: " tip-bot for Namhyung Kim
2013-09-11 5:09 ` [PATCH 7/9] perf tools: Save failed result of get_srcline() Namhyung Kim
2013-10-15 5:26 ` [tip:perf/core] " tip-bot for Namhyung Kim
2013-09-11 5:09 ` Namhyung Kim [this message]
2013-10-15 5:26 ` [tip:perf/core] perf tools: Implement addr2line directly using libbfd tip-bot for Roberto Vitillo
2013-09-11 5:09 ` [PATCH 9/9] perf tools: Fix srcline sort key behavior Namhyung Kim
2013-10-15 5:26 ` [tip:perf/core] " tip-bot for Namhyung Kim
-- strict thread matches above, loose matches on Subject: below --
2013-08-01 2:55 [PATCH 0/9] perf tools: Enhance and correct srcline behavior Namhyung Kim
2013-08-01 2:55 ` [PATCH 8/9] perf tools: Implement addr2line directly using libbfd Namhyung Kim
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1378876173-13363-9-git-send-email-namhyung@kernel.org \
--to=namhyung@kernel.org \
--cc=a.p.zijlstra@chello.nl \
--cc=acme@ghostprotocols.net \
--cc=jolsa@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=namhyung.kim@lge.com \
--cc=paulus@samba.org \
--cc=ravitillo@lbl.gov \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).