linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v8 1/3] perf annotate: Show raw form for jump instruction with indirect target
@ 2016-12-05 15:56 Ravi Bangoria
  2016-12-05 15:56 ` [PATCH v8 2/3] perf annotate: Support jump instruction with target as second operand Ravi Bangoria
                   ` (5 more replies)
  0 siblings, 6 replies; 13+ messages in thread
From: Ravi Bangoria @ 2016-12-05 15:56 UTC (permalink / raw)
  To: acme
  Cc: peterz, mingo, alexander.shishkin, chris.ryder, mhiramat,
	kim.phillips, treeze.taeung, markus, naveen.n.rao, linux-kernel,
	linuxppc-dev, Ravi Bangoria

For jump instructions that does not include target address as direct
operand, show the original disassembled line for them. This is needed
for certain powerpc jump instructions that use target address in a
register (such as bctr, btar, ...).

Before:
     ld     r12,32088(r12)
     mtctr  r12
  v  bctr   ffffffffffffca2c
     std    r2,24(r1)
     addis  r12,r2,-1

After:
     ld     r12,32088(r12)
     mtctr  r12
  v  bctr
     std    r2,24(r1)
     addis  r12,r2,-1

Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
---
Changes in v8:
  - v7: https://lkml.org/lkml/2016/9/21/436
  - Rebase to acme/perf/core
  - No logical changes. (Cross arch annotate patches are in. This patch
    is for hardening annotate for powerpc.)

 tools/perf/util/annotate.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 4012b1d..ea7e0de 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -237,6 +237,9 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
 static int jump__scnprintf(struct ins *ins, char *bf, size_t size,
 			   struct ins_operands *ops)
 {
+	if (!ops->target.addr)
+		return ins__raw_scnprintf(ins, bf, size, ops);
+
 	return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, ops->target.offset);
 }
 
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v8 2/3] perf annotate: Support jump instruction with target as second operand
  2016-12-05 15:56 [PATCH v8 1/3] perf annotate: Show raw form for jump instruction with indirect target Ravi Bangoria
@ 2016-12-05 15:56 ` Ravi Bangoria
  2016-12-06  6:08   ` Ravi Bangoria
                     ` (2 more replies)
  2016-12-05 15:56 ` [PATCH v8 3/3] perf annotate: Fix jump target outside of function address range Ravi Bangoria
                   ` (4 subsequent siblings)
  5 siblings, 3 replies; 13+ messages in thread
From: Ravi Bangoria @ 2016-12-05 15:56 UTC (permalink / raw)
  To: acme
  Cc: peterz, mingo, alexander.shishkin, chris.ryder, mhiramat,
	kim.phillips, treeze.taeung, markus, naveen.n.rao, linux-kernel,
	linuxppc-dev, Ravi Bangoria

Arch like powerpc has jump instructions that includes target address
as second operand. For example, 'bne  cr7,0xc0000000000f6154'. Add
support for such instruction in perf annotate.

objdump o/p:
  c0000000000f6140:   ld     r9,1032(r31)
  c0000000000f6144:   cmpdi  cr7,r9,0
  c0000000000f6148:   bne    cr7,0xc0000000000f6154
  c0000000000f614c:   ld     r9,2312(r30)
  c0000000000f6150:   std    r9,1032(r31)
  c0000000000f6154:   ld     r9,88(r31)

Corresponding perf annotate o/p:

Before patch:
         ld     r9,1032(r31)
         cmpdi  cr7,r9,0
      v  bne    3ffffffffff09f2c
         ld     r9,2312(r30)
         std    r9,1032(r31)
  74:    ld     r9,88(r31)

After patch:
         ld     r9,1032(r31)
         cmpdi  cr7,r9,0
      v  bne    74
         ld     r9,2312(r30)
         std    r9,1032(r31)
  74:    ld     r9,88(r31)

Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
---
Changes in v8:
  - v7: https://lkml.org/lkml/2016/9/21/436
  - Rebase to acme/perf/core
  - Little change in patch description.
  - No logical changes. (Cross arch annotate patches are in. This patch
    is for hardening annotate for powerpc.)

 tools/perf/util/annotate.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index ea7e0de..590244e 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -223,8 +223,12 @@ bool ins__is_call(const struct ins *ins)
 static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map *map __maybe_unused)
 {
 	const char *s = strchr(ops->raw, '+');
+	const char *c = strchr(ops->raw, ',');
 
-	ops->target.addr = strtoull(ops->raw, NULL, 16);
+	if (c++ != NULL)
+		ops->target.addr = strtoull(c, NULL, 16);
+	else
+		ops->target.addr = strtoull(ops->raw, NULL, 16);
 
 	if (s++ != NULL)
 		ops->target.offset = strtoull(s, NULL, 16);
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v8 3/3] perf annotate: Fix jump target outside of function address range
  2016-12-05 15:56 [PATCH v8 1/3] perf annotate: Show raw form for jump instruction with indirect target Ravi Bangoria
  2016-12-05 15:56 ` [PATCH v8 2/3] perf annotate: Support jump instruction with target as second operand Ravi Bangoria
@ 2016-12-05 15:56 ` Ravi Bangoria
  2016-12-13 16:27   ` Arnaldo Carvalho de Melo
  2016-12-20 19:26   ` [tip:perf/urgent] " tip-bot for Ravi Bangoria
  2016-12-05 19:22 ` [PATCH v8 1/3] perf annotate: Show raw form for jump instruction with indirect target Arnaldo Carvalho de Melo
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 13+ messages in thread
From: Ravi Bangoria @ 2016-12-05 15:56 UTC (permalink / raw)
  To: acme
  Cc: peterz, mingo, alexander.shishkin, chris.ryder, mhiramat,
	kim.phillips, treeze.taeung, markus, naveen.n.rao, linux-kernel,
	linuxppc-dev, Ravi Bangoria

If jump target is outside of function range, perf is not handling it
correctly. Especially when target address is lesser than function start
address, target offset will be negative. But, target address declared
to be unsigned, converts negative number into 2's complement. See below
example. Here target of 'jumpq' instruction at 34cf8 is 34ac0 which is
lesser than function start address(34cf0).

        34ac0 - 34cf0 = -0x230 = 0xfffffffffffffdd0

Objdump output:

  0000000000034cf0 <__sigaction>:
  __GI___sigaction():
    34cf0: lea    -0x20(%rdi),%eax
    34cf3: cmp    -bashx1,%eax
    34cf6: jbe    34d00 <__sigaction+0x10>
    34cf8: jmpq   34ac0 <__GI___libc_sigaction>
    34cfd: nopl   (%rax)
    34d00: mov    0x386161(%rip),%rax        # 3bae68 <_DYNAMIC+0x2e8>
    34d07: movl   -bashx16,%fs:(%rax)
    34d0e: mov    -bashxffffffff,%eax
    34d13: retq

perf annotate before applying patch:

  __GI___sigaction  /usr/lib64/libc-2.22.so
           lea    -0x20(%rdi),%eax
           cmp    -bashx1,%eax
        v  jbe    10
        v  jmpq   fffffffffffffdd0
           nop
    10:    mov    _DYNAMIC+0x2e8,%rax
           movl   -bashx16,%fs:(%rax)
           mov    -bashxffffffff,%eax
           retq

perf annotate after applying patch:

  __GI___sigaction  /usr/lib64/libc-2.22.so
           lea    -0x20(%rdi),%eax
           cmp    -bashx1,%eax
        v  jbe    10
        ^  jmpq   34ac0 <__GI___libc_sigaction>
           nop
    10:    mov    _DYNAMIC+0x2e8,%rax
           movl   -bashx16,%fs:(%rax)
           mov    -bashxffffffff,%eax
           retq

Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
---
Changes in v8:
  - v7: https://lkml.org/lkml/2016/9/21/436
  - Rebased to acme/perf/core.
  - No logical changes. (Cross arch annotate patches are in. This patch
    is for hardening annotate.)

tools/perf/ui/browsers/annotate.c |  5 +++--
 tools/perf/util/annotate.c        | 14 +++++++++-----
 tools/perf/util/annotate.h        |  5 +++--
 3 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index ec7a30f..ba36aac 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -215,7 +215,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
 			ui_browser__set_color(browser, color);
 		if (dl->ins.ops && dl->ins.ops->scnprintf) {
 			if (ins__is_jump(&dl->ins)) {
-				bool fwd = dl->ops.target.offset > (u64)dl->offset;
+				bool fwd = dl->ops.target.offset > dl->offset;
 
 				ui_browser__write_graph(browser, fwd ? SLSMG_DARROW_CHAR :
 								    SLSMG_UARROW_CHAR);
@@ -245,7 +245,8 @@ static bool disasm_line__is_valid_jump(struct disasm_line *dl, struct symbol *sy
 {
 	if (!dl || !dl->ins.ops || !ins__is_jump(&dl->ins)
 	    || !disasm_line__has_offset(dl)
-	    || dl->ops.target.offset >= symbol__size(sym))
+	    || dl->ops.target.offset < 0
+	    || dl->ops.target.offset >= (s64)symbol__size(sym))
 		return false;
 
 	return true;
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 590244e..c81a395 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -230,10 +230,12 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
 	else
 		ops->target.addr = strtoull(ops->raw, NULL, 16);
 
-	if (s++ != NULL)
+	if (s++ != NULL) {
 		ops->target.offset = strtoull(s, NULL, 16);
-	else
-		ops->target.offset = UINT64_MAX;
+		ops->target.offset_avail = true;
+	} else {
+		ops->target.offset_avail = false;
+	}
 
 	return 0;
 }
@@ -241,7 +243,7 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
 static int jump__scnprintf(struct ins *ins, char *bf, size_t size,
 			   struct ins_operands *ops)
 {
-	if (!ops->target.addr)
+	if (!ops->target.addr || ops->target.offset < 0)
 		return ins__raw_scnprintf(ins, bf, size, ops);
 
 	return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, ops->target.offset);
@@ -1209,9 +1211,11 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
 	if (dl == NULL)
 		return -1;
 
-	if (dl->ops.target.offset == UINT64_MAX)
+	if (!disasm_line__has_offset(dl)) {
 		dl->ops.target.offset = dl->ops.target.addr -
 					map__rip_2objdump(map, sym->start);
+		dl->ops.target.offset_avail = true;
+	}
 
 	/* kcore has no symbols, so add the call target name */
 	if (dl->ins.ops && ins__is_call(&dl->ins) && !dl->ops.target.name) {
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 87e4cad..09776b5 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -24,7 +24,8 @@ struct ins_operands {
 		char	*raw;
 		char	*name;
 		u64	addr;
-		u64	offset;
+		s64	offset;
+		bool	offset_avail;
 	} target;
 	union {
 		struct {
@@ -68,7 +69,7 @@ struct disasm_line {
 
 static inline bool disasm_line__has_offset(const struct disasm_line *dl)
 {
-	return dl->ops.target.offset != UINT64_MAX;
+	return dl->ops.target.offset_avail;
 }
 
 void disasm_line__free(struct disasm_line *dl);
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v8 1/3] perf annotate: Show raw form for jump instruction with indirect target
  2016-12-05 15:56 [PATCH v8 1/3] perf annotate: Show raw form for jump instruction with indirect target Ravi Bangoria
  2016-12-05 15:56 ` [PATCH v8 2/3] perf annotate: Support jump instruction with target as second operand Ravi Bangoria
  2016-12-05 15:56 ` [PATCH v8 3/3] perf annotate: Fix jump target outside of function address range Ravi Bangoria
@ 2016-12-05 19:22 ` Arnaldo Carvalho de Melo
  2016-12-05 20:21 ` Arnaldo Carvalho de Melo
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 13+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-12-05 19:22 UTC (permalink / raw)
  To: Ravi Bangoria
  Cc: peterz, mingo, alexander.shishkin, chris.ryder, mhiramat,
	kim.phillips, treeze.taeung, markus, naveen.n.rao, linux-kernel,
	linuxppc-dev

Em Mon, Dec 05, 2016 at 09:26:45PM +0530, Ravi Bangoria escreveu:
> For jump instructions that does not include target address as direct
> operand, show the original disassembled line for them. This is needed
> for certain powerpc jump instructions that use target address in a
> register (such as bctr, btar, ...).

Please, mention the name of the function where you copy annotated
examples from, so that I can reproduce it here, using the files you
provided (perf.data and vmlinux for powerpc).

Searching one such function now...
 
> Before:
>      ld     r12,32088(r12)
>      mtctr  r12
>   v  bctr   ffffffffffffca2c
>      std    r2,24(r1)
>      addis  r12,r2,-1
> 
> After:
>      ld     r12,32088(r12)
>      mtctr  r12
>   v  bctr
>      std    r2,24(r1)
>      addis  r12,r2,-1
> 
> Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
> Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
> ---
> Changes in v8:
>   - v7: https://lkml.org/lkml/2016/9/21/436
>   - Rebase to acme/perf/core
>   - No logical changes. (Cross arch annotate patches are in. This patch
>     is for hardening annotate for powerpc.)
> 
>  tools/perf/util/annotate.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
> index 4012b1d..ea7e0de 100644
> --- a/tools/perf/util/annotate.c
> +++ b/tools/perf/util/annotate.c
> @@ -237,6 +237,9 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
>  static int jump__scnprintf(struct ins *ins, char *bf, size_t size,
>  			   struct ins_operands *ops)
>  {
> +	if (!ops->target.addr)
> +		return ins__raw_scnprintf(ins, bf, size, ops);
> +
>  	return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, ops->target.offset);
>  }
>  
> -- 
> 2.4.11

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v8 1/3] perf annotate: Show raw form for jump instruction with indirect target
  2016-12-05 15:56 [PATCH v8 1/3] perf annotate: Show raw form for jump instruction with indirect target Ravi Bangoria
                   ` (2 preceding siblings ...)
  2016-12-05 19:22 ` [PATCH v8 1/3] perf annotate: Show raw form for jump instruction with indirect target Arnaldo Carvalho de Melo
@ 2016-12-05 20:21 ` Arnaldo Carvalho de Melo
  2016-12-05 20:31   ` Arnaldo Carvalho de Melo
  2016-12-06  8:30 ` [tip:perf/core] " tip-bot for Ravi Bangoria
  2016-12-13 16:15 ` [PATCH v8 1/3] " Ravi Bangoria
  5 siblings, 1 reply; 13+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-12-05 20:21 UTC (permalink / raw)
  To: Ravi Bangoria
  Cc: peterz, mingo, alexander.shishkin, chris.ryder, mhiramat,
	kim.phillips, treeze.taeung, markus, naveen.n.rao, linux-kernel,
	linuxppc-dev

Em Mon, Dec 05, 2016 at 09:26:45PM +0530, Ravi Bangoria escreveu:
> For jump instructions that does not include target address as direct
> operand, show the original disassembled line for them. This is needed
> for certain powerpc jump instructions that use target address in a
> register (such as bctr, btar, ...).

Found it, .__bpf_prog_run, that is present in that perf.data file you
sent me, has it, will use it in my committer notes for this patch.

- Arnaldo

> 
> Before:
>      ld     r12,32088(r12)
>      mtctr  r12
>   v  bctr   ffffffffffffca2c
>      std    r2,24(r1)
>      addis  r12,r2,-1
> 
> After:
>      ld     r12,32088(r12)
>      mtctr  r12
>   v  bctr
>      std    r2,24(r1)
>      addis  r12,r2,-1
> 
> Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
> Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
> ---
> Changes in v8:
>   - v7: https://lkml.org/lkml/2016/9/21/436
>   - Rebase to acme/perf/core
>   - No logical changes. (Cross arch annotate patches are in. This patch
>     is for hardening annotate for powerpc.)
> 
>  tools/perf/util/annotate.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
> index 4012b1d..ea7e0de 100644
> --- a/tools/perf/util/annotate.c
> +++ b/tools/perf/util/annotate.c
> @@ -237,6 +237,9 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
>  static int jump__scnprintf(struct ins *ins, char *bf, size_t size,
>  			   struct ins_operands *ops)
>  {
> +	if (!ops->target.addr)
> +		return ins__raw_scnprintf(ins, bf, size, ops);
> +
>  	return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, ops->target.offset);
>  }
>  
> -- 
> 2.4.11

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v8 1/3] perf annotate: Show raw form for jump instruction with indirect target
  2016-12-05 20:21 ` Arnaldo Carvalho de Melo
@ 2016-12-05 20:31   ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 13+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-12-05 20:31 UTC (permalink / raw)
  To: Ravi Bangoria
  Cc: peterz, mingo, alexander.shishkin, chris.ryder, mhiramat,
	kim.phillips, treeze.taeung, markus, naveen.n.rao, linux-kernel,
	linuxppc-dev

Em Mon, Dec 05, 2016 at 05:21:42PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Mon, Dec 05, 2016 at 09:26:45PM +0530, Ravi Bangoria escreveu:
> > For jump instructions that does not include target address as direct
> > operand, show the original disassembled line for them. This is needed
> > for certain powerpc jump instructions that use target address in a
> > register (such as bctr, btar, ...).
> 
> Found it, .__bpf_prog_run, that is present in that perf.data file you
> sent me, has it, will use it in my committer notes for this patch.

So, I've added these committer notes while testing it, will continue
processing your patches later/tomorrow, thanks!

    Committer notes:
    
    Testing it using a perf.data file and vmlinux for powerpc64,
    cross-annotating it on a x86_64 workstation:
    
    Before:
    
      .__bpf_prog_run  vmlinux.powerpc
             │        std    r10,512(r9)                      ▒
             │        lbz    r9,0(r31)                        ▒
             │        rldicr r9,r9,3,60                       ▒
             │        ldx    r9,r30,r9                        ▒
             │        mtctr  r9                               ▒
      100.00 │      ↓ bctr   3fffffffffe01510                 ▒
             │        lwa    r10,4(r31)                       ▒
             │        lwz    r9,0(r31)                        ▒
      <SNIP>
      Invalid jump offset: 3fffffffffe01510
    
    After:
    
      .__bpf_prog_run  vmlinux.powerpc
             │        std    r10,512(r9)                      ▒
             │        lbz    r9,0(r31)                        ▒
             │        rldicr r9,r9,3,60                       ▒
             │        ldx    r9,r30,r9                        ▒
             │        mtctr  r9                               ▒
      100.00 │      ↓ bctr                                    ▒
             │        lwa    r10,4(r31)                       ▒
             │        lwz    r9,0(r31)                        ▒
      <SNIP>
      Invalid jump offset: 3fffffffffe01510
    
    This, in turn, uncovers another problem with jumps without operands, the
    ENTER/-> operation, to jump to the target, still continues using the bogus
    target :-)
    
    BTW, this was the file used for the above tests:
    
      [acme@jouet ravi_bangoria]$ perf report --header-only -i perf.data.f22vm.powerdev
      # ========
      # captured on: Thu Nov 24 12:40:38 2016
      # hostname : pdev-f22-qemu
      # os release : 4.4.10-200.fc22.ppc64
      # perf version : 4.9.rc1.g6298ce
      # arch : ppc64
      # nrcpus online : 48
      # nrcpus avail : 48
      # cpudesc : POWER7 (architected), altivec supported
      # cpuid : 74,513
      # total memory : 4158976 kB
      # cmdline : /home/ravi/Workspace/linux/tools/perf/perf record -a
      # event : name = cycles:ppp, , size = 112, { sample_period, sample_freq } = 4000, sample_type = IP|TID|TIME|CPU|PERIOD, disabled = 1, inherit = 1, mmap = 1, c
      # HEADER_CPU_TOPOLOGY info available, use -I to display
      # HEADER_NUMA_TOPOLOGY info available, use -I to display
      # pmu mappings: cpu = 4, software = 1, tracepoint = 2, breakpoint = 5
      # missing features: HEADER_TRACING_DATA HEADER_BRANCH_STACK HEADER_GROUP_DESC HEADER_AUXTRACE HEADER_STAT HEADER_CACHE
      # ========
      #
      [acme@jouet ravi_bangoria]$
    
    Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
    Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
    Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
 
> - Arnaldo
> 
> > 
> > Before:
> >      ld     r12,32088(r12)
> >      mtctr  r12
> >   v  bctr   ffffffffffffca2c
> >      std    r2,24(r1)
> >      addis  r12,r2,-1
> > 
> > After:
> >      ld     r12,32088(r12)
> >      mtctr  r12
> >   v  bctr
> >      std    r2,24(r1)
> >      addis  r12,r2,-1
> > 
> > Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
> > Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
> > ---
> > Changes in v8:
> >   - v7: https://lkml.org/lkml/2016/9/21/436
> >   - Rebase to acme/perf/core
> >   - No logical changes. (Cross arch annotate patches are in. This patch
> >     is for hardening annotate for powerpc.)
> > 
> >  tools/perf/util/annotate.c | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
> > index 4012b1d..ea7e0de 100644
> > --- a/tools/perf/util/annotate.c
> > +++ b/tools/perf/util/annotate.c
> > @@ -237,6 +237,9 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
> >  static int jump__scnprintf(struct ins *ins, char *bf, size_t size,
> >  			   struct ins_operands *ops)
> >  {
> > +	if (!ops->target.addr)
> > +		return ins__raw_scnprintf(ins, bf, size, ops);
> > +
> >  	return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, ops->target.offset);
> >  }
> >  
> > -- 
> > 2.4.11

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v8 2/3] perf annotate: Support jump instruction with target as second operand
  2016-12-05 15:56 ` [PATCH v8 2/3] perf annotate: Support jump instruction with target as second operand Ravi Bangoria
@ 2016-12-06  6:08   ` Ravi Bangoria
  2016-12-13 16:23   ` Arnaldo Carvalho de Melo
  2016-12-20 19:25   ` [tip:perf/urgent] " tip-bot for Ravi Bangoria
  2 siblings, 0 replies; 13+ messages in thread
From: Ravi Bangoria @ 2016-12-06  6:08 UTC (permalink / raw)
  To: acme, kim.phillips
  Cc: peterz, mingo, alexander.shishkin, chris.ryder, mhiramat,
	treeze.taeung, markus, naveen.n.rao, linux-kernel, linuxppc-dev,
	Ravi Bangoria

Hi Arnaldo,

Hmm, so it's difficult to find example of this when we use debuginfo.
Because...

Jump__parse tries to look for two things 'offset' and 'target address'.

objdump with debuginfo will include offset in assembly f.e. annotate of
'smp_call_function_single' with perf.data and vmlinux I shared.

       │c00000000016d6ac:   cmpwi  cr7,r9,0                                                    ▒
       │c00000000016d6b0: ↑ bne    cr7,c00000000016d59c <.smp_call_function_single+0x8c>       ▒
       │c00000000016d6b4:   addis  r10,r2,-15                                                  ▒

objdump of same function with kcore.

       │c00000000016d6ac:   cmpwi  cr7,r9,0                                                    ▒
       │c00000000016d6b0: ↓ bne    cr7,0xc00000000016d59c                                      ▒
       │c00000000016d6b4:   addis  r10,r2,-15                                                  ▒

Annotating in first case won't show any issue because we directly get
offset. But in this case as well, we are parsing wrong target address
in ops->target.addr

While we don't have offset in second case, we use target address to
find it. And thus it shows wrong o/p something like:

       │       cmpwi  cr7,r9,0                                                                 ▒
       │     ↓ bne    3fffffffffe92afc                                                         ▒
       │       addis  r10,r2,-15                                                               ▒

BTW, we have lot of such instructions in kernel.

Thanks,
-Ravi


On Monday 05 December 2016 09:26 PM, Ravi Bangoria wrote:
> Arch like powerpc has jump instructions that includes target address
> as second operand. For example, 'bne  cr7,0xc0000000000f6154'. Add
> support for such instruction in perf annotate.
>
> objdump o/p:
>   c0000000000f6140:   ld     r9,1032(r31)
>   c0000000000f6144:   cmpdi  cr7,r9,0
>   c0000000000f6148:   bne    cr7,0xc0000000000f6154
>   c0000000000f614c:   ld     r9,2312(r30)
>   c0000000000f6150:   std    r9,1032(r31)
>   c0000000000f6154:   ld     r9,88(r31)
>
> Corresponding perf annotate o/p:
>
> Before patch:
>          ld     r9,1032(r31)
>          cmpdi  cr7,r9,0
>       v  bne    3ffffffffff09f2c
>          ld     r9,2312(r30)
>          std    r9,1032(r31)
>   74:    ld     r9,88(r31)
>
> After patch:
>          ld     r9,1032(r31)
>          cmpdi  cr7,r9,0
>       v  bne    74
>          ld     r9,2312(r30)
>          std    r9,1032(r31)
>   74:    ld     r9,88(r31)
>
> Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
> ---
> Changes in v8:
>   - v7: https://lkml.org/lkml/2016/9/21/436
>   - Rebase to acme/perf/core
>   - Little change in patch description.
>   - No logical changes. (Cross arch annotate patches are in. This patch
>     is for hardening annotate for powerpc.)
>
>  tools/perf/util/annotate.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
> index ea7e0de..590244e 100644
> --- a/tools/perf/util/annotate.c
> +++ b/tools/perf/util/annotate.c
> @@ -223,8 +223,12 @@ bool ins__is_call(const struct ins *ins)
>  static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map *map __maybe_unused)
>  {
>  	const char *s = strchr(ops->raw, '+');
> +	const char *c = strchr(ops->raw, ',');
>
> -	ops->target.addr = strtoull(ops->raw, NULL, 16);
> +	if (c++ != NULL)
> +		ops->target.addr = strtoull(c, NULL, 16);
> +	else
> +		ops->target.addr = strtoull(ops->raw, NULL, 16);
>
>  	if (s++ != NULL)
>  		ops->target.offset = strtoull(s, NULL, 16);

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [tip:perf/core] perf annotate: Show raw form for jump instruction with indirect target
  2016-12-05 15:56 [PATCH v8 1/3] perf annotate: Show raw form for jump instruction with indirect target Ravi Bangoria
                   ` (3 preceding siblings ...)
  2016-12-05 20:21 ` Arnaldo Carvalho de Melo
@ 2016-12-06  8:30 ` tip-bot for Ravi Bangoria
  2016-12-13 16:15 ` [PATCH v8 1/3] " Ravi Bangoria
  5 siblings, 0 replies; 13+ messages in thread
From: tip-bot for Ravi Bangoria @ 2016-12-06  8:30 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mpe, mingo, kim.phillips, naveen.n.rao, mhiramat, acme, peterz,
	alexander.shishkin, markus, tglx, treeze.taeung, chris.ryder,
	ravi.bangoria, linux-kernel, hpa

Commit-ID:  bec60e50af83741cde1786ab475d4bf472aed6f9
Gitweb:     http://git.kernel.org/tip/bec60e50af83741cde1786ab475d4bf472aed6f9
Author:     Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
AuthorDate: Mon, 5 Dec 2016 21:26:45 +0530
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 5 Dec 2016 17:21:57 -0300

perf annotate: Show raw form for jump instruction with indirect target

For jump instructions that does not include target address as direct operand,
show the original disassembled line for them. This is needed for certain
powerpc jump instructions that use target address in a register (such as bctr,
btar, ...).

Before:
     ld     r12,32088(r12)
     mtctr  r12
  v  bctr   ffffffffffffca2c
     std    r2,24(r1)
     addis  r12,r2,-1

After:
     ld     r12,32088(r12)
     mtctr  r12
  v  bctr
     std    r2,24(r1)
     addis  r12,r2,-1

Committer notes:

Testing it using a perf.data file and vmlinux for powerpc64,
cross-annotating it on a x86_64 workstation:

Before:

  .__bpf_prog_run  vmlinux.powerpc
         │        std    r10,512(r9)                      ▒
         │        lbz    r9,0(r31)                        ▒
         │        rldicr r9,r9,3,60                       ▒
         │        ldx    r9,r30,r9                        ▒
         │        mtctr  r9                               ▒
  100.00 │      ↓ bctr   3fffffffffe01510                 ▒
         │        lwa    r10,4(r31)                       ▒
         │        lwz    r9,0(r31)                        ▒
  <SNIP>
  Invalid jump offset: 3fffffffffe01510

After:

  .__bpf_prog_run  vmlinux.powerpc
         │        std    r10,512(r9)                      ▒
         │        lbz    r9,0(r31)                        ▒
         │        rldicr r9,r9,3,60                       ▒
         │        ldx    r9,r30,r9                        ▒
         │        mtctr  r9                               ▒
  100.00 │      ↓ bctr                                    ▒
         │        lwa    r10,4(r31)                       ▒
         │        lwz    r9,0(r31)                        ▒
  <SNIP>
  Invalid jump offset: 3fffffffffe01510

This, in turn, uncovers another problem with jumps without operands, the
ENTER/-> operation, to jump to the target, still continues using the bogus
target :-)

BTW, this was the file used for the above tests:

  [acme@jouet ravi_bangoria]$ perf report --header-only -i perf.data.f22vm.powerdev
  # ========
  # captured on: Thu Nov 24 12:40:38 2016
  # hostname : pdev-f22-qemu
  # os release : 4.4.10-200.fc22.ppc64
  # perf version : 4.9.rc1.g6298ce
  # arch : ppc64
  # nrcpus online : 48
  # nrcpus avail : 48
  # cpudesc : POWER7 (architected), altivec supported
  # cpuid : 74,513
  # total memory : 4158976 kB
  # cmdline : /home/ravi/Workspace/linux/tools/perf/perf record -a
  # event : name = cycles:ppp, , size = 112, { sample_period, sample_freq } = 4000, sample_type = IP|TID|TIME|CPU|PERIOD, disabled = 1, inherit = 1, mmap = 1, c
  # HEADER_CPU_TOPOLOGY info available, use -I to display
  # HEADER_NUMA_TOPOLOGY info available, use -I to display
  # pmu mappings: cpu = 4, software = 1, tracepoint = 2, breakpoint = 5
  # missing features: HEADER_TRACING_DATA HEADER_BRANCH_STACK HEADER_GROUP_DESC HEADER_AUXTRACE HEADER_STAT HEADER_CACHE
  # ========
  #
  [acme@jouet ravi_bangoria]$

Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Chris Riyder <chris.ryder@arm.com>
Cc: Kim Phillips <kim.phillips@arm.com>
Cc: Markus Trippelsdorf <markus@trippelsdorf.de>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Taeung Song <treeze.taeung@gmail.com>
Cc: linuxppc-dev@lists.ozlabs.org
Link: http://lkml.kernel.org/r/1480953407-7605-1-git-send-email-ravi.bangoria@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/annotate.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 4012b1d..ea7e0de 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -237,6 +237,9 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
 static int jump__scnprintf(struct ins *ins, char *bf, size_t size,
 			   struct ins_operands *ops)
 {
+	if (!ops->target.addr)
+		return ins__raw_scnprintf(ins, bf, size, ops);
+
 	return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, ops->target.offset);
 }
 

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v8 1/3] perf annotate: Show raw form for jump instruction with indirect target
  2016-12-05 15:56 [PATCH v8 1/3] perf annotate: Show raw form for jump instruction with indirect target Ravi Bangoria
                   ` (4 preceding siblings ...)
  2016-12-06  8:30 ` [tip:perf/core] " tip-bot for Ravi Bangoria
@ 2016-12-13 16:15 ` Ravi Bangoria
  5 siblings, 0 replies; 13+ messages in thread
From: Ravi Bangoria @ 2016-12-13 16:15 UTC (permalink / raw)
  To: acme
  Cc: peterz, mingo, alexander.shishkin, chris.ryder, mhiramat,
	kim.phillips, treeze.taeung, markus, naveen.n.rao, linux-kernel,
	linuxppc-dev, Ravi Bangoria

Hi Arnaldo,

Can you please review 2nd and 3rd patch.

-Ravi

On Monday 05 December 2016 09:26 PM, Ravi Bangoria wrote:
> For jump instructions that does not include target address as direct
> operand, show the original disassembled line for them. This is needed
> for certain powerpc jump instructions that use target address in a
> register (such as bctr, btar, ...).
>
> Before:
>      ld     r12,32088(r12)
>      mtctr  r12
>   v  bctr   ffffffffffffca2c
>      std    r2,24(r1)
>      addis  r12,r2,-1
>
> After:
>      ld     r12,32088(r12)
>      mtctr  r12
>   v  bctr
>      std    r2,24(r1)
>      addis  r12,r2,-1
>
> Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
> Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
> ---
> Changes in v8:
>   - v7: https://lkml.org/lkml/2016/9/21/436
>   - Rebase to acme/perf/core
>   - No logical changes. (Cross arch annotate patches are in. This patch
>     is for hardening annotate for powerpc.)
>
>  tools/perf/util/annotate.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
> index 4012b1d..ea7e0de 100644
> --- a/tools/perf/util/annotate.c
> +++ b/tools/perf/util/annotate.c
> @@ -237,6 +237,9 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
>  static int jump__scnprintf(struct ins *ins, char *bf, size_t size,
>  			   struct ins_operands *ops)
>  {
> +	if (!ops->target.addr)
> +		return ins__raw_scnprintf(ins, bf, size, ops);
> +
>  	return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, ops->target.offset);
>  }
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v8 2/3] perf annotate: Support jump instruction with target as second operand
  2016-12-05 15:56 ` [PATCH v8 2/3] perf annotate: Support jump instruction with target as second operand Ravi Bangoria
  2016-12-06  6:08   ` Ravi Bangoria
@ 2016-12-13 16:23   ` Arnaldo Carvalho de Melo
  2016-12-20 19:25   ` [tip:perf/urgent] " tip-bot for Ravi Bangoria
  2 siblings, 0 replies; 13+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-12-13 16:23 UTC (permalink / raw)
  To: Ravi Bangoria
  Cc: peterz, mingo, alexander.shishkin, chris.ryder, mhiramat,
	kim.phillips, treeze.taeung, markus, naveen.n.rao, linux-kernel,
	linuxppc-dev

Em Mon, Dec 05, 2016 at 09:26:46PM +0530, Ravi Bangoria escreveu:
> +++ b/tools/perf/util/annotate.c
> @@ -223,8 +223,12 @@ bool ins__is_call(const struct ins *ins)
>  static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map *map __maybe_unused)
>  {
>  	const char *s = strchr(ops->raw, '+');
> +	const char *c = strchr(ops->raw, ',');
>  
> -	ops->target.addr = strtoull(ops->raw, NULL, 16);
> +	if (c++ != NULL)
> +		ops->target.addr = strtoull(c, NULL, 16);
> +	else
> +		ops->target.addr = strtoull(ops->raw, NULL, 16);
>  
>  	if (s++ != NULL)
>  		ops->target.offset = strtoull(s, NULL, 16);

Simple enough, applied.

- Arnaldo

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v8 3/3] perf annotate: Fix jump target outside of function address range
  2016-12-05 15:56 ` [PATCH v8 3/3] perf annotate: Fix jump target outside of function address range Ravi Bangoria
@ 2016-12-13 16:27   ` Arnaldo Carvalho de Melo
  2016-12-20 19:26   ` [tip:perf/urgent] " tip-bot for Ravi Bangoria
  1 sibling, 0 replies; 13+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-12-13 16:27 UTC (permalink / raw)
  To: Ravi Bangoria
  Cc: peterz, mingo, alexander.shishkin, chris.ryder, mhiramat,
	kim.phillips, treeze.taeung, markus, naveen.n.rao, linux-kernel,
	linuxppc-dev

Em Mon, Dec 05, 2016 at 09:26:47PM +0530, Ravi Bangoria escreveu:
> If jump target is outside of function range, perf is not handling it
> correctly. Especially when target address is lesser than function start
> address, target offset will be negative. But, target address declared
> to be unsigned, converts negative number into 2's complement. See below
> example. Here target of 'jumpq' instruction at 34cf8 is 34ac0 which is
> lesser than function start address(34cf0).
> 
>         34ac0 - 34cf0 = -0x230 = 0xfffffffffffffdd0

Looks ok, applied.

- Arnaldo
 
> Objdump output:
> 
>   0000000000034cf0 <__sigaction>:
>   __GI___sigaction():
>     34cf0: lea    -0x20(%rdi),%eax
>     34cf3: cmp    -bashx1,%eax
>     34cf6: jbe    34d00 <__sigaction+0x10>
>     34cf8: jmpq   34ac0 <__GI___libc_sigaction>
>     34cfd: nopl   (%rax)
>     34d00: mov    0x386161(%rip),%rax        # 3bae68 <_DYNAMIC+0x2e8>
>     34d07: movl   -bashx16,%fs:(%rax)
>     34d0e: mov    -bashxffffffff,%eax
>     34d13: retq
> 
> perf annotate before applying patch:
> 
>   __GI___sigaction  /usr/lib64/libc-2.22.so
>            lea    -0x20(%rdi),%eax
>            cmp    -bashx1,%eax
>         v  jbe    10
>         v  jmpq   fffffffffffffdd0
>            nop
>     10:    mov    _DYNAMIC+0x2e8,%rax
>            movl   -bashx16,%fs:(%rax)
>            mov    -bashxffffffff,%eax
>            retq
> 
> perf annotate after applying patch:
> 
>   __GI___sigaction  /usr/lib64/libc-2.22.so
>            lea    -0x20(%rdi),%eax
>            cmp    -bashx1,%eax
>         v  jbe    10
>         ^  jmpq   34ac0 <__GI___libc_sigaction>
>            nop
>     10:    mov    _DYNAMIC+0x2e8,%rax
>            movl   -bashx16,%fs:(%rax)
>            mov    -bashxffffffff,%eax
>            retq
> 
> Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
> ---
> Changes in v8:
>   - v7: https://lkml.org/lkml/2016/9/21/436
>   - Rebased to acme/perf/core.
>   - No logical changes. (Cross arch annotate patches are in. This patch
>     is for hardening annotate.)
> 
> tools/perf/ui/browsers/annotate.c |  5 +++--
>  tools/perf/util/annotate.c        | 14 +++++++++-----
>  tools/perf/util/annotate.h        |  5 +++--
>  3 files changed, 15 insertions(+), 9 deletions(-)
> 
> diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
> index ec7a30f..ba36aac 100644
> --- a/tools/perf/ui/browsers/annotate.c
> +++ b/tools/perf/ui/browsers/annotate.c
> @@ -215,7 +215,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
>  			ui_browser__set_color(browser, color);
>  		if (dl->ins.ops && dl->ins.ops->scnprintf) {
>  			if (ins__is_jump(&dl->ins)) {
> -				bool fwd = dl->ops.target.offset > (u64)dl->offset;
> +				bool fwd = dl->ops.target.offset > dl->offset;
>  
>  				ui_browser__write_graph(browser, fwd ? SLSMG_DARROW_CHAR :
>  								    SLSMG_UARROW_CHAR);
> @@ -245,7 +245,8 @@ static bool disasm_line__is_valid_jump(struct disasm_line *dl, struct symbol *sy
>  {
>  	if (!dl || !dl->ins.ops || !ins__is_jump(&dl->ins)
>  	    || !disasm_line__has_offset(dl)
> -	    || dl->ops.target.offset >= symbol__size(sym))
> +	    || dl->ops.target.offset < 0
> +	    || dl->ops.target.offset >= (s64)symbol__size(sym))
>  		return false;
>  
>  	return true;
> diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
> index 590244e..c81a395 100644
> --- a/tools/perf/util/annotate.c
> +++ b/tools/perf/util/annotate.c
> @@ -230,10 +230,12 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
>  	else
>  		ops->target.addr = strtoull(ops->raw, NULL, 16);
>  
> -	if (s++ != NULL)
> +	if (s++ != NULL) {
>  		ops->target.offset = strtoull(s, NULL, 16);
> -	else
> -		ops->target.offset = UINT64_MAX;
> +		ops->target.offset_avail = true;
> +	} else {
> +		ops->target.offset_avail = false;
> +	}
>  
>  	return 0;
>  }
> @@ -241,7 +243,7 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
>  static int jump__scnprintf(struct ins *ins, char *bf, size_t size,
>  			   struct ins_operands *ops)
>  {
> -	if (!ops->target.addr)
> +	if (!ops->target.addr || ops->target.offset < 0)
>  		return ins__raw_scnprintf(ins, bf, size, ops);
>  
>  	return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, ops->target.offset);
> @@ -1209,9 +1211,11 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
>  	if (dl == NULL)
>  		return -1;
>  
> -	if (dl->ops.target.offset == UINT64_MAX)
> +	if (!disasm_line__has_offset(dl)) {
>  		dl->ops.target.offset = dl->ops.target.addr -
>  					map__rip_2objdump(map, sym->start);
> +		dl->ops.target.offset_avail = true;
> +	}
>  
>  	/* kcore has no symbols, so add the call target name */
>  	if (dl->ins.ops && ins__is_call(&dl->ins) && !dl->ops.target.name) {
> diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
> index 87e4cad..09776b5 100644
> --- a/tools/perf/util/annotate.h
> +++ b/tools/perf/util/annotate.h
> @@ -24,7 +24,8 @@ struct ins_operands {
>  		char	*raw;
>  		char	*name;
>  		u64	addr;
> -		u64	offset;
> +		s64	offset;
> +		bool	offset_avail;
>  	} target;
>  	union {
>  		struct {
> @@ -68,7 +69,7 @@ struct disasm_line {
>  
>  static inline bool disasm_line__has_offset(const struct disasm_line *dl)
>  {
> -	return dl->ops.target.offset != UINT64_MAX;
> +	return dl->ops.target.offset_avail;
>  }
>  
>  void disasm_line__free(struct disasm_line *dl);
> -- 
> 2.4.11

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [tip:perf/urgent] perf annotate: Support jump instruction with target as second operand
  2016-12-05 15:56 ` [PATCH v8 2/3] perf annotate: Support jump instruction with target as second operand Ravi Bangoria
  2016-12-06  6:08   ` Ravi Bangoria
  2016-12-13 16:23   ` Arnaldo Carvalho de Melo
@ 2016-12-20 19:25   ` tip-bot for Ravi Bangoria
  2 siblings, 0 replies; 13+ messages in thread
From: tip-bot for Ravi Bangoria @ 2016-12-20 19:25 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: ravi.bangoria, hpa, kim.phillips, mhiramat, chris.ryder, tglx,
	naveen.n.rao, alexander.shishkin, linux-kernel, peterz, markus,
	mingo, acme, treeze.taeung

Commit-ID:  3ee2eb6da20db1edad31070da38996e8e0f8adfa
Gitweb:     http://git.kernel.org/tip/3ee2eb6da20db1edad31070da38996e8e0f8adfa
Author:     Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
AuthorDate: Mon, 5 Dec 2016 21:26:46 +0530
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 15 Dec 2016 16:25:46 -0300

perf annotate: Support jump instruction with target as second operand

Architectures like PowerPC have jump instructions that includes a target
address as a second operand. For example, 'bne cr7,0xc0000000000f6154'.
Add support for such instruction in perf annotate.

objdump o/p:
  c0000000000f6140:   ld     r9,1032(r31)
  c0000000000f6144:   cmpdi  cr7,r9,0
  c0000000000f6148:   bne    cr7,0xc0000000000f6154
  c0000000000f614c:   ld     r9,2312(r30)
  c0000000000f6150:   std    r9,1032(r31)
  c0000000000f6154:   ld     r9,88(r31)

Corresponding perf annotate o/p:

Before patch:
         ld     r9,1032(r31)
         cmpdi  cr7,r9,0
      v  bne    3ffffffffff09f2c
         ld     r9,2312(r30)
         std    r9,1032(r31)
  74:    ld     r9,88(r31)

After patch:
         ld     r9,1032(r31)
         cmpdi  cr7,r9,0
      v  bne    74
         ld     r9,2312(r30)
         std    r9,1032(r31)
  74:    ld     r9,88(r31)

Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Chris Riyder <chris.ryder@arm.com>
Cc: Kim Phillips <kim.phillips@arm.com>
Cc: Markus Trippelsdorf <markus@trippelsdorf.de>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Taeung Song <treeze.taeung@gmail.com>
Cc: linuxppc-dev@lists.ozlabs.org
Link: http://lkml.kernel.org/r/1480953407-7605-2-git-send-email-ravi.bangoria@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/annotate.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index ea7e0de..590244e 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -223,8 +223,12 @@ bool ins__is_call(const struct ins *ins)
 static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map *map __maybe_unused)
 {
 	const char *s = strchr(ops->raw, '+');
+	const char *c = strchr(ops->raw, ',');
 
-	ops->target.addr = strtoull(ops->raw, NULL, 16);
+	if (c++ != NULL)
+		ops->target.addr = strtoull(c, NULL, 16);
+	else
+		ops->target.addr = strtoull(ops->raw, NULL, 16);
 
 	if (s++ != NULL)
 		ops->target.offset = strtoull(s, NULL, 16);

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [tip:perf/urgent] perf annotate: Fix jump target outside of function address range
  2016-12-05 15:56 ` [PATCH v8 3/3] perf annotate: Fix jump target outside of function address range Ravi Bangoria
  2016-12-13 16:27   ` Arnaldo Carvalho de Melo
@ 2016-12-20 19:26   ` tip-bot for Ravi Bangoria
  1 sibling, 0 replies; 13+ messages in thread
From: tip-bot for Ravi Bangoria @ 2016-12-20 19:26 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, naveen.n.rao, alexander.shishkin, mingo, markus,
	chris.ryder, peterz, hpa, treeze.taeung, mhiramat, tglx,
	ravi.bangoria, kim.phillips, linux-kernel

Commit-ID:  e216874cc1946d28084fa90e495e02725a29e25f
Gitweb:     http://git.kernel.org/tip/e216874cc1946d28084fa90e495e02725a29e25f
Author:     Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
AuthorDate: Mon, 5 Dec 2016 21:26:47 +0530
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 15 Dec 2016 16:25:46 -0300

perf annotate: Fix jump target outside of function address range

If jump target is outside of function range, perf is not handling it
correctly. Especially when target address is lesser than function start
address, target offset will be negative. But, target address declared to
be unsigned, converts negative number into 2's complement. See below
example. Here target of 'jumpq' instruction at 34cf8 is 34ac0 which is
lesser than function start address(34cf0).

        34ac0 - 34cf0 = -0x230 = 0xfffffffffffffdd0

Objdump output:

  0000000000034cf0 <__sigaction>:
  __GI___sigaction():
    34cf0: lea    -0x20(%rdi),%eax
    34cf3: cmp    -bashx1,%eax
    34cf6: jbe    34d00 <__sigaction+0x10>
    34cf8: jmpq   34ac0 <__GI___libc_sigaction>
    34cfd: nopl   (%rax)
    34d00: mov    0x386161(%rip),%rax        # 3bae68 <_DYNAMIC+0x2e8>
    34d07: movl   -bashx16,%fs:(%rax)
    34d0e: mov    -bashxffffffff,%eax
    34d13: retq

perf annotate before applying patch:

  __GI___sigaction  /usr/lib64/libc-2.22.so
           lea    -0x20(%rdi),%eax
           cmp    -bashx1,%eax
        v  jbe    10
        v  jmpq   fffffffffffffdd0
           nop
    10:    mov    _DYNAMIC+0x2e8,%rax
           movl   -bashx16,%fs:(%rax)
           mov    -bashxffffffff,%eax
           retq

perf annotate after applying patch:

  __GI___sigaction  /usr/lib64/libc-2.22.so
           lea    -0x20(%rdi),%eax
           cmp    -bashx1,%eax
        v  jbe    10
        ^  jmpq   34ac0 <__GI___libc_sigaction>
           nop
    10:    mov    _DYNAMIC+0x2e8,%rax
           movl   -bashx16,%fs:(%rax)
           mov    -bashxffffffff,%eax
           retq

Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Chris Riyder <chris.ryder@arm.com>
Cc: Kim Phillips <kim.phillips@arm.com>
Cc: Markus Trippelsdorf <markus@trippelsdorf.de>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Taeung Song <treeze.taeung@gmail.com>
Cc: linuxppc-dev@lists.ozlabs.org
Link: http://lkml.kernel.org/r/1480953407-7605-3-git-send-email-ravi.bangoria@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/ui/browsers/annotate.c |  5 +++--
 tools/perf/util/annotate.c        | 14 +++++++++-----
 tools/perf/util/annotate.h        |  5 +++--
 3 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index ec7a30f..ba36aac 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -215,7 +215,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
 			ui_browser__set_color(browser, color);
 		if (dl->ins.ops && dl->ins.ops->scnprintf) {
 			if (ins__is_jump(&dl->ins)) {
-				bool fwd = dl->ops.target.offset > (u64)dl->offset;
+				bool fwd = dl->ops.target.offset > dl->offset;
 
 				ui_browser__write_graph(browser, fwd ? SLSMG_DARROW_CHAR :
 								    SLSMG_UARROW_CHAR);
@@ -245,7 +245,8 @@ static bool disasm_line__is_valid_jump(struct disasm_line *dl, struct symbol *sy
 {
 	if (!dl || !dl->ins.ops || !ins__is_jump(&dl->ins)
 	    || !disasm_line__has_offset(dl)
-	    || dl->ops.target.offset >= symbol__size(sym))
+	    || dl->ops.target.offset < 0
+	    || dl->ops.target.offset >= (s64)symbol__size(sym))
 		return false;
 
 	return true;
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 590244e..c81a395 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -230,10 +230,12 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
 	else
 		ops->target.addr = strtoull(ops->raw, NULL, 16);
 
-	if (s++ != NULL)
+	if (s++ != NULL) {
 		ops->target.offset = strtoull(s, NULL, 16);
-	else
-		ops->target.offset = UINT64_MAX;
+		ops->target.offset_avail = true;
+	} else {
+		ops->target.offset_avail = false;
+	}
 
 	return 0;
 }
@@ -241,7 +243,7 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
 static int jump__scnprintf(struct ins *ins, char *bf, size_t size,
 			   struct ins_operands *ops)
 {
-	if (!ops->target.addr)
+	if (!ops->target.addr || ops->target.offset < 0)
 		return ins__raw_scnprintf(ins, bf, size, ops);
 
 	return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, ops->target.offset);
@@ -1209,9 +1211,11 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
 	if (dl == NULL)
 		return -1;
 
-	if (dl->ops.target.offset == UINT64_MAX)
+	if (!disasm_line__has_offset(dl)) {
 		dl->ops.target.offset = dl->ops.target.addr -
 					map__rip_2objdump(map, sym->start);
+		dl->ops.target.offset_avail = true;
+	}
 
 	/* kcore has no symbols, so add the call target name */
 	if (dl->ins.ops && ins__is_call(&dl->ins) && !dl->ops.target.name) {
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 87e4cad..09776b5 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -24,7 +24,8 @@ struct ins_operands {
 		char	*raw;
 		char	*name;
 		u64	addr;
-		u64	offset;
+		s64	offset;
+		bool	offset_avail;
 	} target;
 	union {
 		struct {
@@ -68,7 +69,7 @@ struct disasm_line {
 
 static inline bool disasm_line__has_offset(const struct disasm_line *dl)
 {
-	return dl->ops.target.offset != UINT64_MAX;
+	return dl->ops.target.offset_avail;
 }
 
 void disasm_line__free(struct disasm_line *dl);

^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2016-12-20 19:28 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-05 15:56 [PATCH v8 1/3] perf annotate: Show raw form for jump instruction with indirect target Ravi Bangoria
2016-12-05 15:56 ` [PATCH v8 2/3] perf annotate: Support jump instruction with target as second operand Ravi Bangoria
2016-12-06  6:08   ` Ravi Bangoria
2016-12-13 16:23   ` Arnaldo Carvalho de Melo
2016-12-20 19:25   ` [tip:perf/urgent] " tip-bot for Ravi Bangoria
2016-12-05 15:56 ` [PATCH v8 3/3] perf annotate: Fix jump target outside of function address range Ravi Bangoria
2016-12-13 16:27   ` Arnaldo Carvalho de Melo
2016-12-20 19:26   ` [tip:perf/urgent] " tip-bot for Ravi Bangoria
2016-12-05 19:22 ` [PATCH v8 1/3] perf annotate: Show raw form for jump instruction with indirect target Arnaldo Carvalho de Melo
2016-12-05 20:21 ` Arnaldo Carvalho de Melo
2016-12-05 20:31   ` Arnaldo Carvalho de Melo
2016-12-06  8:30 ` [tip:perf/core] " tip-bot for Ravi Bangoria
2016-12-13 16:15 ` [PATCH v8 1/3] " Ravi Bangoria

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).