perf annotate: Properly interpret indirect call
authorMartin Liška <mliska@suse.cz>
Thu, 23 Aug 2018 12:29:34 +0000 (14:29 +0200)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 30 Aug 2018 17:49:22 +0000 (14:49 -0300)
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>
tools/perf/util/annotate.c

index 20061cf..e62b69e 100644 (file)
@@ -246,8 +246,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;
 }