]> git.baikalelectronics.ru Git - kernel.git/commit
perf unwind: Fix segbase for ld.lld linked objects
authorFangrui Song <maskray@google.com>
Fri, 27 May 2022 18:20:39 +0000 (11:20 -0700)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 3 Jun 2022 19:20:25 +0000 (21:20 +0200)
commit49f3ca99fbb8ab3d2854f4986d6105edf27bc6a2
treed2a7854cd2214c25257644dd0c20ff320df45c62
parente824f0292b62359307b37cb3fc22dda4c7ec2aac
perf unwind: Fix segbase for ld.lld linked objects

segbase is the address of .eh_frame_hdr and table_data is segbase plus
the header size. find_proc_info computes segbase as `map->start +
segbase - map->pgoff` which is wrong when

* .eh_frame_hdr and .text are in different PT_LOAD program headers
* and their p_vaddr difference does not equal their p_offset difference

Since 10.0, ld.lld's default --rosegment -z noseparate-code layout has
such R and RX PT_LOAD program headers.

    ld.lld (default) => perf report fails to unwind `perf record
    --call-graph dwarf` recorded data
    ld.lld --no-rosegment => ok (trivial, no R PT_LOAD)
    ld.lld -z separate-code => ok but by luck: there are two PT_LOAD but
    their p_vaddr difference equals p_offset difference

    ld.bfd -z noseparate-code => ok (trivial, no R PT_LOAD)
    ld.bfd -z separate-code (default for Linux/x86) => ok but by luck:
    there are two PT_LOAD but their p_vaddr difference equals p_offset
    difference

To fix the issue, compute segbase as dso's base address plus
PT_GNU_EH_FRAME's p_vaddr. The base address is computed by iterating
over all dso-associated maps and then subtract the first PT_LOAD p_vaddr
(the minimum guaranteed by generic ABI) from the minimum address.

In libunwind, find_proc_info transitively called by unw_step is cached,
so the iteration overhead is acceptable.

Reported-by: Sebastian Ullrich <sebasti@nullri.ch>
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Fangrui Song <maskray@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: llvm@lists.linux.dev
Link: https://github.com/ClangBuiltLinux/linux/issues/1646
Link: https://lore.kernel.org/r/20220527182039.673248-1-maskray@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/dso.h
tools/perf/util/unwind-libunwind-local.c