[PATCH 4.18 089/168] perf annotate: Properly interpret indirect call

From: Greg Kroah-Hartman
Date: Mon Oct 08 2018 - 14:51:07 EST


4.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: "Martin LiÅka" <mliska@xxxxxxx>

[ Upstream commit 1dc27f63303db58ce1b1a6932d1825305f86d574 ]

The patch changes the parsing of:

callq *0x8(%rbx)

from:

0.26 â â callq *8

to:

0.26 â â callq *0x8(%rbx)

in this case an address is followed by a register, thus one can't parse
only the address.

Committer testing:

1) run 'perf record sleep 10'
2) before applying the patch, run:

perf annotate --stdio2 > /tmp/before

3) after applying the patch, run:

perf annotate --stdio2 > /tmp/after

4) diff /tmp/before /tmp/after:
# --- /tmp/before 2018-08-28 11:16:03.238384143 -0300
# +++ /tmp/after 2018-08-28 11:15:39.335341042 -0300
# @@ -13274,7 +13274,7 @@
# â jle 128
# hash_value = hash_table->hash_func (key);
# mov 0x8(%rsp),%rdi
# - 0.91 â callq *30
# + 0.91 â callq *0x30(%r12)
# mov $0x2,%r8d
# cmp $0x2,%eax
# node_hash = hash_table->hashes[node_index];
# @@ -13848,7 +13848,7 @@
# mov %r14,%rdi
# sub %rbx,%r13
# mov %r13,%rdx
# - â callq *38
# + â callq *0x38(%r15)
# cmp %rax,%r13
# 1.91 â je 240
# 1b4: mov $0xffffffff,%r13d
# @@ -14026,7 +14026,7 @@
# mov %rcx,-0x500(%rbp)
# mov %r15,%rsi
# mov %r14,%rdi
# - â callq *38
# + â callq *0x38(%rax)
# mov -0x500(%rbp),%rcx
# cmp %rax,%rcx
# â jne 9b0
<SNIP tons of other such cases>

Signed-off-by: Martin LiÅka <mliska@xxxxxxx>
Tested-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
Tested-by: Kim Phillips <kim.phillips@xxxxxxx>
Cc: Jiri Olsa <jolsa@xxxxxxxxxx>
Link: http://lkml.kernel.org/r/bd1f3932-be2b-85f9-7582-111ee0a43b07@xxxxxxx
Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
Signed-off-by: Sasha Levin <alexander.levin@xxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
tools/perf/util/annotate.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)

--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -245,8 +245,14 @@ find_target:

indirect_call:
tok = strchr(endptr, '*');
- if (tok != NULL)
- ops->target.addr = strtoull(tok + 1, NULL, 16);
+ if (tok != NULL) {
+ endptr++;
+
+ /* Indirect call can use a non-rip register and offset: callq *0x8(%rbx).
+ * Do not parse such instruction. */
+ if (strstr(endptr, "(%r") == NULL)
+ ops->target.addr = strtoull(endptr, NULL, 16);
+ }
goto find_target;
}