From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
Cc: linux-kernel@vger.kernel.org, kim.phillips@arm.com,
linuxppc-dev@lists.ozlabs.org, peterz@infradead.org,
mingo@redhat.com, alexander.shishkin@linux.intel.com,
treeze.taeung@gmail.com, naveen.n.rao@linux.vnet.ibm.com,
markus@trippelsdorf.de, namhyung@kernel.org, pawel.moll@arm.com,
chris.ryder@arm.com, jolsa@kernel.org, mhiramat@kernel.org
Subject: Re: [PATCH v7 1/6] perf annotate: Add cross arch annotate support
Date: Wed, 5 Oct 2016 08:19:29 -0300 [thread overview]
Message-ID: <20161005111928.GQ7143@kernel.org> (raw)
In-Reply-To: <1474472876-2706-2-git-send-email-ravi.bangoria@linux.vnet.ibm.com>
Em Wed, Sep 21, 2016 at 09:17:51PM +0530, Ravi Bangoria escreveu:
> Change current data structures and function to enable cross arch
> annotate.
>
> Current perf implementation does not support cross arch annotate.
> To make it truly cross arch, instruction table of all arch should
> be present in perf binary. And use appropriate table based on arch
> where perf.data was recorded.
>
> Record on arm:
> $ ./perf record -a
>
> Report -> Annotate on x86:
> $ ./perf report -i perf.data.arm --vmlinux vmlinux.arm
>
> Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
> ---
> Changes in v7:
> - Make norm_arch as global var instead of passing them to each parser.
> - Address other review comments.
>
> tools/perf/builtin-top.c | 2 +-
> tools/perf/ui/browsers/annotate.c | 3 +-
> tools/perf/ui/gtk/annotate.c | 2 +-
> tools/perf/util/annotate.c | 151 ++++++++++++++++++++++++++++++++------
> tools/perf/util/annotate.h | 3 +-
> 5 files changed, 134 insertions(+), 27 deletions(-)
>
> diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
> index 4007857..41ecdd6 100644
> --- a/tools/perf/builtin-top.c
> +++ b/tools/perf/builtin-top.c
> @@ -129,7 +129,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, 0, NULL);
> 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 4c18271..214a14a 100644
> --- a/tools/perf/ui/browsers/annotate.c
> +++ b/tools/perf/ui/browsers/annotate.c
> @@ -1050,7 +1050,8 @@ 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, sizeof_bdl,
> + perf_evsel__env_arch(evsel));
> 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 42d3199..c127aba 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, 0, perf_evsel__env_arch(evsel));
> 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 aeb5a44..816aa2c 100644
> --- a/tools/perf/util/annotate.c
> +++ b/tools/perf/util/annotate.c
> @@ -21,10 +21,13 @@
> #include <regex.h>
> #include <pthread.h>
> #include <linux/bitops.h>
> +#include <sys/utsname.h>
> +#include "../arch/common.h"
>
> const char *disassembler_style;
> const char *objdump_path;
> static regex_t file_lineno;
> +static char *norm_arch;
>
> static struct ins *ins__find(const char *name);
> static int disasm_line__parse(char *line, char **namep, char **rawp);
> @@ -66,10 +69,8 @@ static int call__parse(struct ins_operands *ops, struct map *map)
>
> name++;
>
> -#ifdef __arm__
> - if (strchr(name, '+'))
> + if (!strcmp(norm_arch, "arm") && strchr(name, '+'))
> return -1;
> -#endif
>
> tok = strchr(name, '>');
> if (tok == NULL)
> @@ -252,16 +253,12 @@ 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
> + if (comment == NULL)
> + comment = strchr(s, '#');
>
> - if (comment != NULL)
> - s = comment - 1;
> - else
> - s = strchr(s, '\0') - 1;
> + s = (comment != NULL) ? comment - 1 : strchr(s, '\0') - 1;
Why have you touched the above 4 lines? The code you provided is
equivalent, i.e. has no value for this patch you're working on, just a
distraction for reviewers, please don't do that.
I'll remove it and continue processing the patchkit.
>
> while (s > target && isspace(s[0]))
> --s;
> @@ -364,14 +361,92 @@ bool ins__is_ret(const struct ins *ins)
> return ins->ops == &ret_ops;
> }
>
> -static struct ins instructions[] = {
> +static struct ins instructions_x86[] = {
> { .name = "add", .ops = &mov_ops, },
> { .name = "addl", .ops = &mov_ops, },
> { .name = "addq", .ops = &mov_ops, },
> { .name = "addw", .ops = &mov_ops, },
> { .name = "and", .ops = &mov_ops, },
> -#ifdef __arm__
> - { .name = "b", .ops = &jump_ops, }, // might also be a call
> + { .name = "bts", .ops = &mov_ops, },
> + { .name = "call", .ops = &call_ops, },
> + { .name = "callq", .ops = &call_ops, },
> + { .name = "cmp", .ops = &mov_ops, },
> + { .name = "cmpb", .ops = &mov_ops, },
> + { .name = "cmpl", .ops = &mov_ops, },
> + { .name = "cmpq", .ops = &mov_ops, },
> + { .name = "cmpw", .ops = &mov_ops, },
> + { .name = "cmpxch", .ops = &mov_ops, },
> + { .name = "dec", .ops = &dec_ops, },
> + { .name = "decl", .ops = &dec_ops, },
> + { .name = "imul", .ops = &mov_ops, },
> + { .name = "inc", .ops = &dec_ops, },
> + { .name = "incl", .ops = &dec_ops, },
> + { .name = "ja", .ops = &jump_ops, },
> + { .name = "jae", .ops = &jump_ops, },
> + { .name = "jb", .ops = &jump_ops, },
> + { .name = "jbe", .ops = &jump_ops, },
> + { .name = "jc", .ops = &jump_ops, },
> + { .name = "jcxz", .ops = &jump_ops, },
> + { .name = "je", .ops = &jump_ops, },
> + { .name = "jecxz", .ops = &jump_ops, },
> + { .name = "jg", .ops = &jump_ops, },
> + { .name = "jge", .ops = &jump_ops, },
> + { .name = "jl", .ops = &jump_ops, },
> + { .name = "jle", .ops = &jump_ops, },
> + { .name = "jmp", .ops = &jump_ops, },
> + { .name = "jmpq", .ops = &jump_ops, },
> + { .name = "jna", .ops = &jump_ops, },
> + { .name = "jnae", .ops = &jump_ops, },
> + { .name = "jnb", .ops = &jump_ops, },
> + { .name = "jnbe", .ops = &jump_ops, },
> + { .name = "jnc", .ops = &jump_ops, },
> + { .name = "jne", .ops = &jump_ops, },
> + { .name = "jng", .ops = &jump_ops, },
> + { .name = "jnge", .ops = &jump_ops, },
> + { .name = "jnl", .ops = &jump_ops, },
> + { .name = "jnle", .ops = &jump_ops, },
> + { .name = "jno", .ops = &jump_ops, },
> + { .name = "jnp", .ops = &jump_ops, },
> + { .name = "jns", .ops = &jump_ops, },
> + { .name = "jnz", .ops = &jump_ops, },
> + { .name = "jo", .ops = &jump_ops, },
> + { .name = "jp", .ops = &jump_ops, },
> + { .name = "jpe", .ops = &jump_ops, },
> + { .name = "jpo", .ops = &jump_ops, },
> + { .name = "jrcxz", .ops = &jump_ops, },
> + { .name = "js", .ops = &jump_ops, },
> + { .name = "jz", .ops = &jump_ops, },
> + { .name = "lea", .ops = &mov_ops, },
> + { .name = "lock", .ops = &lock_ops, },
> + { .name = "mov", .ops = &mov_ops, },
> + { .name = "movb", .ops = &mov_ops, },
> + { .name = "movdqa", .ops = &mov_ops, },
> + { .name = "movl", .ops = &mov_ops, },
> + { .name = "movq", .ops = &mov_ops, },
> + { .name = "movslq", .ops = &mov_ops, },
> + { .name = "movzbl", .ops = &mov_ops, },
> + { .name = "movzwl", .ops = &mov_ops, },
> + { .name = "nop", .ops = &nop_ops, },
> + { .name = "nopl", .ops = &nop_ops, },
> + { .name = "nopw", .ops = &nop_ops, },
> + { .name = "or", .ops = &mov_ops, },
> + { .name = "orl", .ops = &mov_ops, },
> + { .name = "test", .ops = &mov_ops, },
> + { .name = "testb", .ops = &mov_ops, },
> + { .name = "testl", .ops = &mov_ops, },
> + { .name = "xadd", .ops = &mov_ops, },
> + { .name = "xbeginl", .ops = &jump_ops, },
> + { .name = "xbeginq", .ops = &jump_ops, },
> + { .name = "retq", .ops = &ret_ops, },
> +};
> +
> +static struct ins instructions_arm[] = {
> + { .name = "add", .ops = &mov_ops, },
> + { .name = "addl", .ops = &mov_ops, },
> + { .name = "addq", .ops = &mov_ops, },
> + { .name = "addw", .ops = &mov_ops, },
> + { .name = "and", .ops = &mov_ops, },
> + { .name = "b", .ops = &jump_ops, }, /* might also be a call */
> { .name = "bcc", .ops = &jump_ops, },
> { .name = "bcs", .ops = &jump_ops, },
> { .name = "beq", .ops = &jump_ops, },
> @@ -383,7 +458,6 @@ static struct ins instructions[] = {
> { .name = "blt", .ops = &jump_ops, },
> { .name = "blx", .ops = &call_ops, },
> { .name = "bne", .ops = &jump_ops, },
> -#endif
> { .name = "bts", .ops = &mov_ops, },
> { .name = "call", .ops = &call_ops, },
> { .name = "callq", .ops = &call_ops, },
> @@ -472,24 +546,48 @@ static int ins__cmp(const void *a, const void *b)
> return strcmp(ia->name, ib->name);
> }
>
> -static void ins__sort(void)
> +static void ins__sort(struct ins *instructions, int nmemb)
> {
> - const int nmemb = ARRAY_SIZE(instructions);
> -
> qsort(instructions, nmemb, sizeof(struct ins), ins__cmp);
> }
>
> +static const char *annotate__norm_arch(char *arch)
> +{
> + struct utsname uts;
> +
> + if (!arch) { /* Assume we are annotating locally. */
> + if (uname(&uts) < 0)
> + return NULL;
> + arch = uts.machine;
> + }
> + return normalize_arch(arch);
> +}
> +
> static struct ins *ins__find(const char *name)
> {
> - const int nmemb = ARRAY_SIZE(instructions);
> static bool sorted;
> + struct ins *instructions;
> + int nmemb;
>
> if (!sorted) {
> - ins__sort();
> + ins__sort(instructions_x86, ARRAY_SIZE(instructions_x86));
> + ins__sort(instructions_arm, ARRAY_SIZE(instructions_arm));
> sorted = true;
> }
>
> - return bsearch(name, instructions, nmemb, sizeof(struct ins), ins__key_cmp);
> + if (!strcmp(norm_arch, "x86")) {
> + instructions = instructions_x86;
> + nmemb = ARRAY_SIZE(instructions_x86);
> + } else if (!strcmp(norm_arch, "arm")) {
> + instructions = instructions_arm;
> + nmemb = ARRAY_SIZE(instructions_arm);
> + } else {
> + pr_err("perf annotate not supported by %s arch\n", norm_arch);
> + return NULL;
> + }
> +
> + return bsearch(name, instructions, nmemb, sizeof(struct ins),
> + ins__key_cmp);
> }
>
> int symbol__alloc_hist(struct symbol *sym)
> @@ -1280,7 +1378,8 @@ fallback:
> return 0;
> }
>
> -int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize)
> +int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize,
> + char *arch)
> {
> struct dso *dso = map->dso;
> char command[PATH_MAX * 2];
> @@ -1297,6 +1396,12 @@ int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize)
> if (err)
> return err;
>
> + norm_arch = (char *) annotate__norm_arch(arch);
> + if (!norm_arch) {
> + pr_err("Can not annotate. Could not determine architecture.");
> + return -1;
> + }
> +
> 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));
> @@ -1793,7 +1898,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, 0, perf_evsel__env_arch(evsel)) < 0)
> return -1;
>
> len = symbol__size(sym);
> diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
> index 5bbcec1..4400269 100644
> --- a/tools/perf/util/annotate.h
> +++ b/tools/perf/util/annotate.h
> @@ -156,7 +156,8 @@ 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, size_t privsize,
> + char *arch);
>
> enum symbol_disassemble_errno {
> SYMBOL_ANNOTATE_ERRNO__SUCCESS = 0,
> --
> 2.5.5
next prev parent reply other threads:[~2016-10-05 11:19 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-09-21 15:47 [PATCH v7 0/6] perf annotate: Cross arch support + few fixes Ravi Bangoria
2016-09-21 15:47 ` [PATCH v7 1/6] perf annotate: Add cross arch annotate support Ravi Bangoria
2016-10-05 11:19 ` Arnaldo Carvalho de Melo [this message]
2016-10-10 13:26 ` Ravi Bangoria
2016-09-21 15:47 ` [PATCH v7 2/6] perf annotate: Add support for powerpc Ravi Bangoria
2016-10-05 11:22 ` Arnaldo Carvalho de Melo
2016-09-21 15:47 ` [PATCH v7 3/6] perf annotate: Show raw form for jump instruction with indirect target Ravi Bangoria
2016-10-05 11:27 ` Arnaldo Carvalho de Melo
2016-10-10 13:31 ` Ravi Bangoria
2016-09-21 15:47 ` [PATCH v7 4/6] perf annotate: Support jump instruction with target as second operand Ravi Bangoria
2016-10-05 11:28 ` Arnaldo Carvalho de Melo
2016-10-10 13:34 ` Ravi Bangoria
2016-09-21 15:47 ` [PATCH v7 5/6] perf annotate: Fix jump target outside of function address range Ravi Bangoria
2016-10-05 11:31 ` Arnaldo Carvalho de Melo
2016-10-10 13:37 ` Ravi Bangoria
2016-09-21 15:47 ` [PATCH v7 6/6] perf annotate: cross arch annotate support fixes for ARM Ravi Bangoria
2016-10-05 11:34 ` Arnaldo Carvalho de Melo
2016-10-10 13:46 ` Ravi Bangoria
2016-10-10 15:57 ` Kim Phillips
2016-09-21 19:34 ` [PATCH v7 0/6] perf annotate: Cross arch support + few fixes Kim Phillips
2016-09-22 5:18 ` Ravi Bangoria
2016-09-22 14:58 ` Kim Phillips
2016-09-27 15:28 ` Ravi Bangoria
2016-10-10 13:59 ` [PATCH] perf annotate: Cleanup arch specific stuff Ravi Bangoria
2016-10-10 16:24 ` Arnaldo Carvalho de Melo
2016-10-10 16:39 ` Naveen N. Rao
2016-10-10 16:49 ` Ravi Bangoria
2016-10-10 16:56 ` Arnaldo Carvalho de Melo
2016-10-17 14:43 ` Ravi Bangoria
2016-10-17 14:45 ` Arnaldo Carvalho de Melo
2016-10-17 14:49 ` Ravi Bangoria
2016-11-16 9:18 ` [PATCH v7 0/6] perf annotate: Cross arch support + few fixes Naveen N. Rao
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=20161005111928.GQ7143@kernel.org \
--to=acme@kernel.org \
--cc=alexander.shishkin@linux.intel.com \
--cc=chris.ryder@arm.com \
--cc=jolsa@kernel.org \
--cc=kim.phillips@arm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=markus@trippelsdorf.de \
--cc=mhiramat@kernel.org \
--cc=mingo@redhat.com \
--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 \
/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.