Implement dwarf variable/type resolving for perf script

From: Andi Kleen
Date: Mon Nov 27 2017 - 19:24:18 EST


This patchkit extends perf script to query dwarf information for variable
names or types/structure fields accessed from code.

The dwarf resolution is all on top of Masami's perf probe dwarf code.

It supports multiple use cases:
- When we sample registers it can use the dwarf information to resolve
the registers to names.
- When we sample any instruction the instruction can be decoded and
we can determine the type/struct field to make an estimate of the
memory access patterns in data structures.
- When we sample the new PTWRITE instruction the logged value from
the PT log can be associated with a variable.
- Various cleanups and fixes to make the one above all possible.

It is all implemented with new output formats in perf script:
iregval (map register values to names) and insnvar (decode instruction
and map back memory operand to dwarf operation)

There are some limitations, it cannot decode everything, and is
somewhat slow, but it's already quite useful for typical code


% perf record -Idi,si ./targ
% perf script -F +iregvals
...
targ 8584 169763.761843: 2091795 cycles:ppp: 40041a main (targ)
targ 8584 169763.762520: 1913932 cycles:ppp: 400534 f1 (targ) { b = 0x2, int } { a = 0x1, int }
targ 8584 169763.763141: 1638913 cycles:ppp: 400523 f2 (targ) { b = 0x1, int } { a = 0x2, int }
targ 8584 169763.763672: 1516522 cycles:ppp: 400522 f2 (targ) { b = 0x1, int } { a = 0x2, int }
targ 8584 169763.764165: 1335501 cycles:ppp: 400523 f2 (targ) { b = 0x1, int } { a = 0x2, int }
targ 8584 169763.764598: 1253289 cycles:ppp: 400522 f2 (targ) { b = 0x2, int } { a = 0x1, int }
targ 8584 169763.765005: 1135131 cycles:ppp: 400534 f1 (targ) { b = 0x2, int } { a = 0x1, int }
targ 8584 169763.765373: 1080325 cycles:ppp: 400522 f2 (targ) { b = 0x2, int } { a = 0x1, int }
targ 8584 169763.765724: 1036999 cycles:ppp: 400522 f2 (targ) { b = 0x1, int } { a = 0x2, int }
targ 8584 169763.766061: 971213 cycles:ppp: 400534 f1 (targ) { b = 0x2, int } { a = 0x1, int }


% perf record -e intel_pt//u -a sleep 1
% perf script --itrace=i0ns -F insnvar,insn,ip,sym -f 2>&1 | xed -F insn: -A -64 | less
...
4f7e61 xyarray__max_y pushq %rbp
4f7e62 xyarray__max_y mov %rsp, %rbp
4f7e65 xyarray__max_y sub $0x20, %rsp
4f7e69 xyarray__max_y movq %rdi, -0x18(%rbp) { -24(xy), struct xyarray* }
4f7e6d xyarray__max_y movq %fs:0x28, %rax
4f7e76 xyarray__max_y movq %rax, -0x8(%rbp) { -8(xy), struct xyarray* }
4f7e7a xyarray__max_y xor %eax, %eax
4f7e7c xyarray__max_y movq -0x18(%rbp), %rax { -24(xy), struct xyarray* }
4f7e80 xyarray__max_y movq 0x20(%rax), %rax
4f7e84 xyarray__max_y movq -0x8(%rbp), %rdx { -8(xy), struct xyarray* }
4f7e88 xyarray__max_y xorq %fs:0x28, %rdx
4f7e91 xyarray__max_y jz 0x7
4f7e98 xyarray__max_y leaveq
4f7e99 xyarray__max_y retq

In this example we now know that this function accesses two fields in struct xyarray *

Available from

git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-misc perf/var-resolve-2

v1: Initial post