All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Ingo Molnar <mingo@kernel.org>
Cc: linux-kernel@vger.kernel.org,
	Arnaldo Carvalho de Melo <acme@redhat.com>,
	Adrian Hunter <adrian.hunter@intel.com>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Chris Riyder <chris.ryder@arm.com>,
	David Ahern <dsahern@gmail.com>, Jiri Olsa <jolsa@kernel.org>,
	Kim Phillips <kim.phillips@arm.com>,
	Markus Trippelsdorf <markus@trippelsdorf.de>,
	Masami Hiramatsu <mhiramat@kernel.org>,
	Namhyung Kim <namhyung@kernel.org>,
	"Naveen N . Rao" <naveen.n.rao@linux.vnet.ibm.com>,
	Pawel Moll <pawel.moll@arm.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>,
	Taeung Song <treeze.taeung@gmail.com>,
	Wang Nan <wangnan0@huawei.com>
Subject: [PATCH 01/18] perf annotate: Start supporting cross arch annotation
Date: Wed, 23 Nov 2016 13:40:01 -0300	[thread overview]
Message-ID: <1479919218-6367-2-git-send-email-acme@kernel.org> (raw)
In-Reply-To: <1479919218-6367-1-git-send-email-acme@kernel.org>

From: Arnaldo Carvalho de Melo <acme@redhat.com>

Introduce a 'struct arch', where arch specific stuff will live, starting
with objdump's choice of comment delimitation character, that is '#' in
x86 while a ';' in arm.

This has some bits and pieces from a patch submitted by Ravi.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Chris Riyder <chris.ryder@arm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kim Phillips <kim.phillips@arm.com>
Cc: Markus Trippelsdorf <markus@trippelsdorf.de>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
Cc: Taeung Song <treeze.taeung@gmail.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-f337tzjjcl8vtapgvjxmhrbx@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-top.c          |   2 +-
 tools/perf/ui/browsers/annotate.c |   2 +-
 tools/perf/ui/gtk/annotate.c      |   2 +-
 tools/perf/util/annotate.c        | 114 ++++++++++++++++++++++++++++++++------
 tools/perf/util/annotate.h        |   6 +-
 5 files changed, 103 insertions(+), 23 deletions(-)

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index fe3af9535e85..3df4178ba378 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -130,7 +130,7 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he)
 		return err;
 	}
 
-	err = symbol__disassemble(sym, map, 0);
+	err = symbol__disassemble(sym, map, NULL, 0);
 	if (err == 0) {
 out_assign:
 		top->sym_filter_entry = he;
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index 4c18271c71c9..e6e9f7d80dbd 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -1050,7 +1050,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,
 		  (nr_pcnt - 1);
 	}
 
-	err = symbol__disassemble(sym, map, sizeof_bdl);
+	err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), sizeof_bdl);
 	if (err) {
 		char msg[BUFSIZ];
 		symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg));
diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c
index 42d319927762..8c9308ac30b7 100644
--- a/tools/perf/ui/gtk/annotate.c
+++ b/tools/perf/ui/gtk/annotate.c
@@ -167,7 +167,7 @@ static int symbol__gtk_annotate(struct symbol *sym, struct map *map,
 	if (map->dso->annotate_warned)
 		return -1;
 
-	err = symbol__disassemble(sym, map, 0);
+	err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), 0);
 	if (err) {
 		char msg[BUFSIZ];
 		symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg));
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index aeb5a441bd74..1ba41a27214d 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -18,9 +18,11 @@
 #include "annotate.h"
 #include "evsel.h"
 #include "block-range.h"
+#include "arch/common.h"
 #include <regex.h>
 #include <pthread.h>
 #include <linux/bitops.h>
+#include <sys/utsname.h>
 
 const char 	*disassembler_style;
 const char	*objdump_path;
@@ -29,6 +31,28 @@ static regex_t	 file_lineno;
 static struct ins *ins__find(const char *name);
 static int disasm_line__parse(char *line, char **namep, char **rawp);
 
+struct arch {
+	const char	*name;
+	struct		{
+		char comment_char;
+	} objdump;
+};
+
+static struct arch architectures[] = {
+	{
+		.name = "arm",
+		.objdump =  {
+			.comment_char = ';',
+		},
+	},
+	{
+		.name = "x86",
+		.objdump =  {
+			.comment_char = '#',
+		},
+	},
+};
+
 static void ins__delete(struct ins_operands *ops)
 {
 	if (ops == NULL)
@@ -54,7 +78,7 @@ int ins__scnprintf(struct ins *ins, char *bf, size_t size,
 	return ins__raw_scnprintf(ins, bf, size, ops);
 }
 
-static int call__parse(struct ins_operands *ops, struct map *map)
+static int call__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map *map)
 {
 	char *endptr, *tok, *name;
 
@@ -118,7 +142,7 @@ bool ins__is_call(const struct ins *ins)
 	return ins->ops == &call_ops;
 }
 
-static int jump__parse(struct ins_operands *ops, struct map *map __maybe_unused)
+static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map *map __maybe_unused)
 {
 	const char *s = strchr(ops->raw, '+');
 
@@ -173,7 +197,7 @@ static int comment__symbol(char *raw, char *comment, u64 *addrp, char **namep)
 	return 0;
 }
 
-static int lock__parse(struct ins_operands *ops, struct map *map)
+static int lock__parse(struct arch *arch, struct ins_operands *ops, struct map *map)
 {
 	char *name;
 
@@ -194,7 +218,7 @@ static int lock__parse(struct ins_operands *ops, struct map *map)
 		return 0;
 
 	if (ops->locked.ins->ops->parse &&
-	    ops->locked.ins->ops->parse(ops->locked.ops, map) < 0)
+	    ops->locked.ins->ops->parse(arch, ops->locked.ops, map) < 0)
 		goto out_free_ops;
 
 	return 0;
@@ -237,7 +261,7 @@ static struct ins_ops lock_ops = {
 	.scnprintf = lock__scnprintf,
 };
 
-static int mov__parse(struct ins_operands *ops, struct map *map __maybe_unused)
+static int mov__parse(struct arch *arch, struct ins_operands *ops, struct map *map __maybe_unused)
 {
 	char *s = strchr(ops->raw, ','), *target, *comment, prev;
 
@@ -252,11 +276,7 @@ static int mov__parse(struct ins_operands *ops, struct map *map __maybe_unused)
 		return -1;
 
 	target = ++s;
-#ifdef __arm__
-	comment = strchr(s, ';');
-#else
-	comment = strchr(s, '#');
-#endif
+	comment = strchr(s, arch->objdump.comment_char);
 
 	if (comment != NULL)
 		s = comment - 1;
@@ -304,7 +324,7 @@ static struct ins_ops mov_ops = {
 	.scnprintf = mov__scnprintf,
 };
 
-static int dec__parse(struct ins_operands *ops, struct map *map __maybe_unused)
+static int dec__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map *map __maybe_unused)
 {
 	char *target, *comment, *s, prev;
 
@@ -492,6 +512,41 @@ static struct ins *ins__find(const char *name)
 	return bsearch(name, instructions, nmemb, sizeof(struct ins), ins__key_cmp);
 }
 
+static int arch__key_cmp(const void *name, const void *archp)
+{
+	const struct arch *arch = archp;
+
+	return strcmp(name, arch->name);
+}
+
+static int arch__cmp(const void *a, const void *b)
+{
+	const struct arch *aa = a;
+	const struct arch *ab = b;
+
+	return strcmp(aa->name, ab->name);
+}
+
+static void arch__sort(void)
+{
+	const int nmemb = ARRAY_SIZE(architectures);
+
+	qsort(architectures, nmemb, sizeof(struct arch), arch__cmp);
+}
+
+static struct arch *arch__find(const char *name)
+{
+	const int nmemb = ARRAY_SIZE(architectures);
+	static bool sorted;
+
+	if (!sorted) {
+		arch__sort();
+		sorted = true;
+	}
+
+	return bsearch(name, architectures, nmemb, sizeof(struct arch), arch__key_cmp);
+}
+
 int symbol__alloc_hist(struct symbol *sym)
 {
 	struct annotation *notes = symbol__annotation(sym);
@@ -709,7 +764,7 @@ int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip)
 	return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip);
 }
 
-static void disasm_line__init_ins(struct disasm_line *dl, struct map *map)
+static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, struct map *map)
 {
 	dl->ins = ins__find(dl->name);
 
@@ -719,7 +774,7 @@ static void disasm_line__init_ins(struct disasm_line *dl, struct map *map)
 	if (!dl->ins->ops)
 		return;
 
-	if (dl->ins->ops->parse && dl->ins->ops->parse(&dl->ops, map) < 0)
+	if (dl->ins->ops->parse && dl->ins->ops->parse(arch, &dl->ops, map) < 0)
 		dl->ins = NULL;
 }
 
@@ -762,6 +817,7 @@ static int disasm_line__parse(char *line, char **namep, char **rawp)
 
 static struct disasm_line *disasm_line__new(s64 offset, char *line,
 					    size_t privsize, int line_nr,
+					    struct arch *arch,
 					    struct map *map)
 {
 	struct disasm_line *dl = zalloc(sizeof(*dl) + privsize);
@@ -777,7 +833,7 @@ static struct disasm_line *disasm_line__new(s64 offset, char *line,
 			if (disasm_line__parse(dl->line, &dl->name, &dl->ops.raw) < 0)
 				goto out_free_line;
 
-			disasm_line__init_ins(dl, map);
+			disasm_line__init_ins(dl, arch, map);
 		}
 	}
 
@@ -1087,6 +1143,7 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st
  * The ops.raw part will be parsed further according to type of the instruction.
  */
 static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
+				      struct arch *arch,
 				      FILE *file, size_t privsize,
 				      int *line_nr)
 {
@@ -1149,7 +1206,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
 			parsed_line = tmp2 + 1;
 	}
 
-	dl = disasm_line__new(offset, parsed_line, privsize, *line_nr, map);
+	dl = disasm_line__new(offset, parsed_line, privsize, *line_nr, arch, map);
 	free(line);
 	(*line_nr)++;
 
@@ -1280,10 +1337,23 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil
 	return 0;
 }
 
-int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize)
+static const char *annotate__norm_arch(const char *arch_name)
+{
+	struct utsname uts;
+
+	if (!arch_name) { /* Assume we are annotating locally. */
+		if (uname(&uts) < 0)
+			return NULL;
+		arch_name = uts.machine;
+	}
+	return normalize_arch((char *)arch_name);
+}
+
+int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_name, size_t privsize)
 {
 	struct dso *dso = map->dso;
 	char command[PATH_MAX * 2];
+	struct arch *arch = NULL;
 	FILE *file;
 	char symfs_filename[PATH_MAX];
 	struct kcore_extract kce;
@@ -1297,6 +1367,14 @@ int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize)
 	if (err)
 		return err;
 
+	arch_name = annotate__norm_arch(arch_name);
+	if (!arch_name)
+		return -1;
+
+	arch = arch__find(arch_name);
+	if (arch == NULL)
+		return -ENOTSUP;
+
 	pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n", __func__,
 		 symfs_filename, sym->name, map->unmap_ip(map, sym->start),
 		 map->unmap_ip(map, sym->end));
@@ -1395,7 +1473,7 @@ int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize)
 
 	nline = 0;
 	while (!feof(file)) {
-		if (symbol__parse_objdump_line(sym, map, file, privsize,
+		if (symbol__parse_objdump_line(sym, map, arch, file, privsize,
 			    &lineno) < 0)
 			break;
 		nline++;
@@ -1793,7 +1871,7 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
 	struct rb_root source_line = RB_ROOT;
 	u64 len;
 
-	if (symbol__disassemble(sym, map, 0) < 0)
+	if (symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), 0) < 0)
 		return -1;
 
 	len = symbol__size(sym);
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 5bbcec173b82..8e490b5c91bc 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -34,9 +34,11 @@ struct ins_operands {
 	};
 };
 
+struct arch;
+
 struct ins_ops {
 	void (*free)(struct ins_operands *ops);
-	int (*parse)(struct ins_operands *ops, struct map *map);
+	int (*parse)(struct arch *arch, struct ins_operands *ops, struct map *map);
 	int (*scnprintf)(struct ins *ins, char *bf, size_t size,
 			 struct ins_operands *ops);
 };
@@ -156,7 +158,7 @@ int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 addr);
 int symbol__alloc_hist(struct symbol *sym);
 void symbol__annotate_zero_histograms(struct symbol *sym);
 
-int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize);
+int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_name, size_t privsize);
 
 enum symbol_disassemble_errno {
 	SYMBOL_ANNOTATE_ERRNO__SUCCESS		= 0,
-- 
2.7.4

  reply	other threads:[~2016-11-23 16:41 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-11-23 16:40 [GIT PULL 00/18] perf/core improvements and fixes Arnaldo Carvalho de Melo
2016-11-23 16:40 ` Arnaldo Carvalho de Melo [this message]
2016-11-23 16:40 ` [PATCH 02/18] perf annotate: Allow arches to specify functions to skip Arnaldo Carvalho de Melo
2016-11-23 16:40 ` [PATCH 03/18] perf annotate: Add per arch instructions annotate handlers Arnaldo Carvalho de Melo
2016-11-23 16:40 ` [PATCH 04/18] tools lib traceevent: Use USECS_PER_SEC instead of hardcoded number Arnaldo Carvalho de Melo
2016-11-23 16:40 ` [PATCH 05/18] tools lib traceevent: Add retrieval of preempt count and latency flags Arnaldo Carvalho de Melo
2016-11-23 16:40 ` [PATCH 06/18] perf tools: Show event fd in debug output Arnaldo Carvalho de Melo
2016-11-23 16:40 ` [PATCH 07/18] perf c2c report: Setup browser after opening perf.data Arnaldo Carvalho de Melo
2016-11-23 16:40 ` [PATCH 08/18] perf c2c report: Add -f/--force option Arnaldo Carvalho de Melo
2016-11-23 16:40 ` [PATCH 09/18] perf c2c report: Add struct c2c_stats::tot_hitm field Arnaldo Carvalho de Melo
2016-11-23 16:40 ` [PATCH 10/18] perf c2c report: Display total HITMs on default Arnaldo Carvalho de Melo
2016-11-23 16:40 ` [PATCH 11/18] perf c2c: Support cascading options Arnaldo Carvalho de Melo
2016-11-23 16:40 ` [PATCH 12/18] perf symbols: Print symbol offsets conditionally Arnaldo Carvalho de Melo
2016-11-23 16:40 ` [PATCH 13/18] perf evsel: Support printing callchains with arrows Arnaldo Carvalho de Melo
2016-11-23 16:40 ` [PATCH 14/18] perf sched timehist: Introduce timehist command Arnaldo Carvalho de Melo
2016-11-23 16:40 ` [PATCH 15/18] perf sched timehist: Add summary options Arnaldo Carvalho de Melo
2016-11-23 16:40 ` [PATCH 16/18] perf sched timehist: Add -w/--wakeups option Arnaldo Carvalho de Melo
2016-11-23 16:40 ` [PATCH 17/18] perf sched timehist: Add call graph options Arnaldo Carvalho de Melo
2016-11-23 16:40 ` [PATCH 18/18] perf sched timehist: Add -V/--cpu-visual option Arnaldo Carvalho de Melo
2016-11-24  4:10 ` [GIT PULL 00/18] perf/core improvements and fixes Ingo Molnar

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=1479919218-6367-2-git-send-email-acme@kernel.org \
    --to=acme@kernel.org \
    --cc=acme@redhat.com \
    --cc=adrian.hunter@intel.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=chris.ryder@arm.com \
    --cc=dsahern@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=kim.phillips@arm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=markus@trippelsdorf.de \
    --cc=mhiramat@kernel.org \
    --cc=mingo@kernel.org \
    --cc=namhyung@kernel.org \
    --cc=naveen.n.rao@linux.vnet.ibm.com \
    --cc=pawel.moll@arm.com \
    --cc=peterz@infradead.org \
    --cc=ravi.bangoria@linux.vnet.ibm.com \
    --cc=treeze.taeung@gmail.com \
    --cc=wangnan0@huawei.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.