simpleperf: Fix handling of BPF symbols

On arm64 BPF JIT programs execute from the vmalloc region[1], which is
typically outside of the [kernel.kallsyms] mapping that starts at _stext
and is used to determine the KASLR offset. As a result, no valid mapping
is found for BPF ksyms, and callchains containing them get discarded.

This breaks profiling of BPF code, and prevents simpleperf from being
used as an external unwinder triggered by BPF programs.

Fix it by creating a separate "fallback" mapping that covers the entire
kernel address space. It reuses the KernelDso object, and is split after
inserting kernel text and module maps, so it's only used to look up syms
outside those regions. With this patch:

  # bpftrace -e 'uprobe:/data/cpueater:foo { unroll(50) { @++ } }' &
  # simpleperf record -g -p $(pidof cpueater) --duration 5
  # simpleperf report
  [...]
  2.83%  [...]  [kernel.kallsyms]  bpf_prog_0a1de85aa6da7d58_foo [bpf]

Note that this doesn't cover the case where BPF programs get (un)loaded
while recording. A comprehensive, but considerably more complex fix may
require parsing PERF_RECORD_KSYMBOL records, and synthesizing them on
startup based on bpf_prog_info for already loaded programs.

[1] https://github.com/torvalds/linux/blob/ffc25326/arch/arm64/net/bpf_jit_comp.c#L1693

Test: atest simpleperf_unit_test
Test: manual (see above)
Change-Id: I001c5d4a093826d207bcf178bab97575105b68d9
3 files changed