Em Fri, Jun 10, 2016 at 06:32:51PM +0530, Naveen N. Rao escreveu: > Convert ins__find() to a __weak function for generic functionality, > while adding a powerpc-specific variant. We look at the function name > for branch instructions and classify the instructions to one among a > branch, a function call (branch with LR update) or a function return > (branch to LR).
How would this allow one to get a perf.data collected on a powerpc system, transfer it to a x86-64 (or aarch64, to mention another workstation wannabe chip) system and then try annotating it? There was a previous discussion about this, and it involved having all yout ppc tables available as well as other arches tables, and then choosing which one to use based on: normalize_arch(thread->mg->machine->env->arch) just like was done for support cross unwinding, see recent patch kit by He Kuang, CCed. - Arnaldo > Cc: Arnaldo Carvalho de Melo <a...@kernel.org> > Cc: Anton Blanchard <an...@ozlabs.org> > Cc: Michael Ellerman <m...@ellerman.id.au> > Cc: Ananth N Mavinakayanahalli <ana...@in.ibm.com> > Reported-by: Anton Blanchard <an...@ozlabs.org> > Signed-off-by: Naveen N. Rao <naveen.n....@linux.vnet.ibm.com> > --- > tools/perf/arch/powerpc/util/Build | 1 + > tools/perf/arch/powerpc/util/annotate.c | 58 > +++++++++++++++++++++++++++++++++ > tools/perf/util/annotate.c | 17 +++++----- > tools/perf/util/annotate.h | 9 +++++ > 4 files changed, 76 insertions(+), 9 deletions(-) > create mode 100644 tools/perf/arch/powerpc/util/annotate.c > > diff --git a/tools/perf/arch/powerpc/util/Build > b/tools/perf/arch/powerpc/util/Build > index 90ad64b..d9e91d6 100644 > --- a/tools/perf/arch/powerpc/util/Build > +++ b/tools/perf/arch/powerpc/util/Build > @@ -2,6 +2,7 @@ libperf-y += header.o > libperf-y += sym-handling.o > libperf-y += kvm-stat.o > libperf-y += perf_regs.o > +libperf-y += annotate.o > > libperf-$(CONFIG_DWARF) += dwarf-regs.o > libperf-$(CONFIG_DWARF) += skip-callchain-idx.o > diff --git a/tools/perf/arch/powerpc/util/annotate.c > b/tools/perf/arch/powerpc/util/annotate.c > new file mode 100644 > index 0000000..f069bd7 > --- /dev/null > +++ b/tools/perf/arch/powerpc/util/annotate.c > @@ -0,0 +1,58 @@ > +#include "perf.h" > +#include "annotate.h" > + > +struct ins *ins__find(const char *name) > +{ > + int i; > + struct ins *ins; > + > + ins = zalloc(sizeof(struct ins)); > + if (!ins) > + return NULL; > + > + ins->name = strdup(name); > + if (!ins->name) > + return NULL; > + > + if (name[0] == 'b') { > + /* branch instructions */ > + ins->ops = &jump_ops; > + > + /* these start with 'b', but aren't branch instructions */ > + if (!strncmp(name, "bcd", 3) || > + !strncmp(name, "brinc", 5) || > + !strncmp(name, "bper", 4)) > + return NULL; > + > + i = strlen(name) - 1; > + if (i < 0) > + return NULL; > + > + /* ignore optional hints at the end of the instructions */ > + if (name[i] == '+' || name[i] == '-') > + i--; > + > + if (name[i] == 'l' || (name[i] == 'a' && name[i-1] == 'l')) { > + /* > + * if the instruction ends up with 'l' or 'la', then > + * those are considered 'calls' since they update LR. > + * ... except for 'bnl' which is branch if not less than > + * and the absolute form of the same. > + */ > + if (strcmp(name, "bnl") && strcmp(name, "bnl+") && > + strcmp(name, "bnl-") && strcmp(name, "bnla") && > + strcmp(name, "bnla+") && strcmp(name, "bnla-")) > + ins->ops = &call_ops; > + } > + if (name[i] == 'r' && name[i-1] == 'l') > + /* > + * instructions ending with 'lr' are considered to be > + * return instructions > + */ > + ins->ops = &ret_ops; > + > + return ins; > + } > + > + return NULL; > +} > diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c > index e871b4e..0fa4fc5 100644 > --- a/tools/perf/util/annotate.c > +++ b/tools/perf/util/annotate.c > @@ -25,7 +25,6 @@ const char *disassembler_style; > const char *objdump_path; > static regex_t file_lineno; > > -static struct ins *ins__find(const char *name); > static int disasm_line__parse(char *line, char **namep, char **rawp); > > static void ins__delete(struct ins_operands *ops) > @@ -107,7 +106,7 @@ static int call__scnprintf(struct ins *ins, char *bf, > size_t size, > return scnprintf(bf, size, "%-6.6s *%" PRIx64, ins->name, > ops->target.addr); > } > > -static struct ins_ops call_ops = { > +struct ins_ops call_ops = { > .parse = call__parse, > .scnprintf = call__scnprintf, > }; > @@ -137,7 +136,7 @@ static int jump__scnprintf(struct ins *ins, char *bf, > size_t size, > return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, > ops->target.offset); > } > > -static struct ins_ops jump_ops = { > +struct ins_ops jump_ops = { > .parse = jump__parse, > .scnprintf = jump__scnprintf, > }; > @@ -230,7 +229,7 @@ static void lock__delete(struct ins_operands *ops) > zfree(&ops->target.name); > } > > -static struct ins_ops lock_ops = { > +struct ins_ops lock_ops = { > .free = lock__delete, > .parse = lock__parse, > .scnprintf = lock__scnprintf, > @@ -298,7 +297,7 @@ static int mov__scnprintf(struct ins *ins, char *bf, > size_t size, > ops->target.name ?: ops->target.raw); > } > > -static struct ins_ops mov_ops = { > +struct ins_ops mov_ops = { > .parse = mov__parse, > .scnprintf = mov__scnprintf, > }; > @@ -339,7 +338,7 @@ static int dec__scnprintf(struct ins *ins, char *bf, > size_t size, > ops->target.name ?: ops->target.raw); > } > > -static struct ins_ops dec_ops = { > +struct ins_ops dec_ops = { > .parse = dec__parse, > .scnprintf = dec__scnprintf, > }; > @@ -350,11 +349,11 @@ static int nop__scnprintf(struct ins *ins > __maybe_unused, char *bf, size_t size, > return scnprintf(bf, size, "%-6.6s", "nop"); > } > > -static struct ins_ops nop_ops = { > +struct ins_ops nop_ops = { > .scnprintf = nop__scnprintf, > }; > > -static struct ins_ops ret_ops = { > +struct ins_ops ret_ops = { > .scnprintf = ins__raw_scnprintf, > }; > > @@ -478,7 +477,7 @@ static void ins__sort(void) > qsort(instructions, nmemb, sizeof(struct ins), ins__cmp); > } > > -static struct ins *ins__find(const char *name) > +__weak struct ins *ins__find(const char *name) > { > const int nmemb = ARRAY_SIZE(instructions); > static bool sorted; > diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h > index 720a4c0..6d89c1d 100644 > --- a/tools/perf/util/annotate.h > +++ b/tools/perf/util/annotate.h > @@ -50,6 +50,15 @@ bool ins__is_jump(const struct ins *ins); > bool ins__is_call(const struct ins *ins); > bool ins__is_ret(const struct ins *ins); > int ins__scnprintf(struct ins *ins, char *bf, size_t size, struct > ins_operands *ops); > +struct ins *ins__find(const char *name); > + > +extern struct ins_ops call_ops; > +extern struct ins_ops jump_ops; > +extern struct ins_ops ret_ops; > +extern struct ins_ops mov_ops; > +extern struct ins_ops lock_ops; > +extern struct ins_ops dec_ops; > +extern struct ins_ops nop_ops; > > struct annotation; > > -- > 2.8.2 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev