diff options
author | Martin Liška <mliska@suse.cz> | 2018-08-23 14:29:34 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-10-10 08:55:59 +0200 |
commit | 4ac14f4b31799184c8eaf69aca4b9bac95f4c019 (patch) | |
tree | 1008c6c88dd8093a17292423cd7885ace6c1293e /tools | |
parent | dbd0ea4cfa2af92724b04e0f63fdf59349e1f9c8 (diff) |
perf annotate: Properly interpret indirect call
[ 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@suse.cz>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Tested-by: Kim Phillips <kim.phillips@arm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/bd1f3932-be2b-85f9-7582-111ee0a43b07@suse.cz
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/util/annotate.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index f91775b4bc3c..31a1e18c7bf2 100644 --- 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; } |