mirror_ubuntu-kernels/tools/perf/util
Leo Yan 3501de9fd9 perf symbol: Correct address for bss symbols
BugLink: https://bugs.launchpad.net/bugs/1989218

[ Upstream commit 2d86612aac ]

When using 'perf mem' and 'perf c2c', an issue is observed that tool
reports the wrong offset for global data symbols.  This is a common
issue on both x86 and Arm64 platforms.

Let's see an example, for a test program, below is the disassembly for
its .bss section which is dumped with objdump:

  ...

  Disassembly of section .bss:

  0000000000004040 <completed.0>:
  	...

  0000000000004080 <buf1>:
  	...

  00000000000040c0 <buf2>:
  	...

  0000000000004100 <thread>:
  	...

First we used 'perf mem record' to run the test program and then used
'perf --debug verbose=4 mem report' to observe what's the symbol info
for 'buf1' and 'buf2' structures.

  # ./perf mem record -e ldlat-loads,ldlat-stores -- false_sharing.exe 8
  # ./perf --debug verbose=4 mem report
    ...
    dso__load_sym_internal: adjusting symbol: st_value: 0x40c0 sh_addr: 0x4040 sh_offset: 0x3028
    symbol__new: buf2 0x30a8-0x30e8
    ...
    dso__load_sym_internal: adjusting symbol: st_value: 0x4080 sh_addr: 0x4040 sh_offset: 0x3028
    symbol__new: buf1 0x3068-0x30a8
    ...

The perf tool relies on libelf to parse symbols, in executable and
shared object files, 'st_value' holds a virtual address; 'sh_addr' is
the address at which section's first byte should reside in memory, and
'sh_offset' is the byte offset from the beginning of the file to the
first byte in the section.  The perf tool uses below formula to convert
a symbol's memory address to a file address:

  file_address = st_value - sh_addr + sh_offset
                    ^
                    ` Memory address

We can see the final adjusted address ranges for buf1 and buf2 are
[0x30a8-0x30e8) and [0x3068-0x30a8) respectively, apparently this is
incorrect, in the code, the structure for 'buf1' and 'buf2' specifies
compiler attribute with 64-byte alignment.

The problem happens for 'sh_offset', libelf returns it as 0x3028 which
is not 64-byte aligned, combining with disassembly, it's likely libelf
doesn't respect the alignment for .bss section, therefore, it doesn't
return the aligned value for 'sh_offset'.

Suggested by Fangrui Song, ELF file contains program header which
contains PT_LOAD segments, the fields p_vaddr and p_offset in PT_LOAD
segments contain the execution info.  A better choice for converting
memory address to file address is using the formula:

  file_address = st_value - p_vaddr + p_offset

This patch introduces elf_read_program_header() which returns the
program header based on the passed 'st_value', then it uses the formula
above to calculate the symbol file address; and the debugging log is
updated respectively.

After applying the change:

  # ./perf --debug verbose=4 mem report
    ...
    dso__load_sym_internal: adjusting symbol: st_value: 0x40c0 p_vaddr: 0x3d28 p_offset: 0x2d28
    symbol__new: buf2 0x30c0-0x3100
    ...
    dso__load_sym_internal: adjusting symbol: st_value: 0x4080 p_vaddr: 0x3d28 p_offset: 0x2d28
    symbol__new: buf1 0x3080-0x30c0
    ...

Fixes: f17e04afaf ("perf report: Fix ELF symbol parsing")
Reported-by: Chang Rui <changruinj@gmail.com>
Suggested-by: Fangrui Song <maskray@google.com>
Signed-off-by: Leo Yan <leo.yan@linaro.org>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20220724060013.171050-2-leo.yan@linaro.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
2022-09-16 10:53:46 +02:00
..
arm-spe-decoder
bpf_skel perf bpf_skel: Do not use typedef to avoid error on old clang 2022-01-04 09:49:21 +01:00
c++
cs-etm-decoder
include
intel-pt-decoder perf intel-pt: Fix missing 'instruction' events with 'q' option 2022-01-04 09:49:16 +01:00
libunwind
scripting-engines
affinity.c
affinity.h
amd-sample-raw.c perf report: Add support to print a textual representation of IBS raw sample data 2021-09-10 18:15:21 -03:00
annotate.c
annotate.h
archinsn.h
arm-spe.c perf arm-spe: Don't set data source if it's not a memory operation 2022-08-26 10:53:50 +02:00
arm-spe.h
auxtrace.c
auxtrace.h
block-info.c
block-info.h
block-range.c
block-range.h
bpf_counter_cgroup.c
bpf_counter.c
bpf_counter.h
bpf_map.c
bpf_map.h
bpf-event.c perf build: Fix check for btf__load_from_kernel_by_id() in libbpf 2022-08-10 09:22:42 +02:00
bpf-event.h
bpf-loader.c perf bpf: Defer freeing string after possible strlen() on it 2022-03-07 11:44:09 +01:00
bpf-loader.h
bpf-prologue.c
bpf-prologue.h
branch.c
branch.h
Build perf report: Add support to print a textual representation of IBS raw sample data 2021-09-10 18:15:21 -03:00
build-id.c perf build-id: Fix caching files with a wrong build ID 2022-08-26 10:54:03 +02:00
build-id.h
cache.h
cacheline.c
cacheline.h
call-path.c
call-path.h
callchain.c
callchain.h
cap.c
cap.h
cgroup.c
cgroup.h
clockid.c
clockid.h
cloexec.c
cloexec.h
color_config.c
color.c
color.h
comm.c
comm.h
compress.h
config.c perf config: Refine error message to eliminate confusion 2021-09-27 09:32:28 -03:00
config.h
copyfile.c
copyfile.h
counts.c
counts.h
cpu-set-sched.h
cpumap.c
cpumap.h
cputopo.c
cputopo.h
cs-etm.c
cs-etm.h
data-convert-bt.c
data-convert-json.c
data-convert.h
data.c perf data: Fix double free in perf_session__delete() 2022-03-07 11:45:57 +01:00
data.h perf tools: Add missing headers needed by util/data.h 2022-08-10 09:24:17 +02:00
db-export.c
db-export.h
debug.c perf script: Fix hex dump character output 2022-01-28 11:03:32 +01:00
debug.h
demangle-java.c
demangle-java.h
demangle-ocaml.c
demangle-ocaml.h
demangle-rust.c
demangle-rust.h
dlfilter.c
dlfilter.h
dso.c perf tools: Allow build-id with trailing zeros 2021-09-11 16:04:47 -03:00
dso.h
dsos.c
dsos.h
dump-insn.c
dump-insn.h
dwarf-aux.c
dwarf-aux.h
dwarf-regs.c
env.c perf bpf: Avoid memory leak from perf_env__insert_btf() 2022-01-04 09:48:48 +01:00
env.h perf bpf: Avoid memory leak from perf_env__insert_btf() 2022-01-04 09:48:48 +01:00
event.c
event.h
events_stats.h
evlist-hybrid.c perf evlist: Fix failed to use cpu list for uncore events 2022-03-07 11:45:57 +01:00
evlist-hybrid.h
evlist.c
evlist.h
evsel_config.h
evsel_fprintf.c
evsel_fprintf.h
evsel.c perf evsel: Override attr->sample_period for non-libpfm4 events 2022-01-28 11:03:26 +01:00
evsel.h perf tools: Factor out copy_config_terms() and free_config_terms() 2021-09-11 16:00:13 -03:00
evswitch.c
evswitch.h
expr.c
expr.h
expr.l
expr.y
find-map.c
fncache.c
fncache.h
genelf_debug.c
genelf.c
genelf.h
generate-cmdlist.sh
get_current_dir_name.c
get_current_dir_name.h
hashmap.c
hashmap.h
header.c Merge branch 'akpm' (patches from Andrew) 2021-09-08 12:55:35 -07:00
header.h
help-unknown-cmd.c
help-unknown-cmd.h
hist.c perf sort: Fix the 'p_stage_cyc' sort key behavior 2022-01-04 09:49:05 +01:00
hist.h perf hist: Fix memory leak of a perf_hpp_fmt 2022-01-04 09:49:06 +01:00
intel-bts.c
intel-bts.h
intel-pt.c perf intel-pt: Fix parsing of VM time correlation arguments 2022-01-21 15:49:21 +01:00
intel-pt.h
intlist.c
intlist.h
iostat.c
iostat.h
jit.h
jitdump.c
jitdump.h
kvm-stat.h
levenshtein.c
levenshtein.h
llvm-utils.c
llvm-utils.h
lzma.c
machine.c perf machine: Initialize srcline string member in add_location struct 2021-09-18 17:43:05 -03:00
machine.h
map_symbol.h
map.c
map.h
maps.h
mem2node.c
mem2node.h
mem-events.c
mem-events.h
memswap.c
memswap.h
metricgroup.c
metricgroup.h
mmap.c
mmap.h
namespaces.c
namespaces.h
ordered-events.c
ordered-events.h
parse-branch-options.c
parse-branch-options.h
parse-events-hybrid.c perf tools: Fix hybrid config terms list corruption 2021-09-11 16:00:34 -03:00
parse-events-hybrid.h
parse-events.c perf tools: Fix misleading add event PMU debug message 2022-05-20 14:42:21 +02:00
parse-events.h
parse-events.l
parse-events.y
parse-regs-options.c
parse-regs-options.h
parse-sublevel-options.c
parse-sublevel-options.h
path.c
path.h
perf_api_probe.c
perf_api_probe.h
perf_event_attr_fprintf.c perf tools: Fix perf_event_attr__fprintf() missing/dupl. fields 2021-09-11 15:58:36 -03:00
perf_regs.c
perf_regs.h
perf-hooks-list.h
perf-hooks.c
perf-hooks.h
PERF-VERSION-GEN
pfm.c
pfm.h
pmu-hybrid.c
pmu-hybrid.h
pmu.c
pmu.h
pmu.l
pmu.y
print_binary.c
print_binary.h
probe-event.c perf probe: Fix ppc64 'perf probe add events failed' case 2022-01-28 11:03:34 +01:00
probe-event.h
probe-file.c
probe-file.h
probe-finder.c
probe-finder.h
pstack.c
pstack.h
python-ext-sources
python.c
rb_resort.h
rblist.c
rblist.h
record.c
record.h
rlimit.c
rlimit.h
rwsem.c
rwsem.h
s390-cpumcf-kernel.h
s390-cpumsf-kernel.h
s390-cpumsf.c
s390-cpumsf.h
s390-sample-raw.c
sample-raw.c perf report: Add support to print a textual representation of IBS raw sample data 2021-09-10 18:15:21 -03:00
sample-raw.h perf report: Add support to print a textual representation of IBS raw sample data 2021-09-10 18:15:21 -03:00
session.c perf session: Remap buf if there is no space for event 2022-05-20 14:41:11 +02:00
session.h
setns.c
setup.py perf python: Fix probing for some clang command line options 2022-05-20 14:41:24 +02:00
sideband_evlist.c
smt.c perf tools: Fix SMT detection fast read path 2022-01-04 09:49:18 +01:00
smt.h
sort.c perf sort: Fix the 'p_stage_cyc' sort key behavior 2022-01-04 09:49:05 +01:00
sort.h perf sort: Fix the 'p_stage_cyc' sort key behavior 2022-01-04 09:49:05 +01:00
spark.c
spark.h
srccode.c
srccode.h
srcline.c
srcline.h
stat-display.c perf stat: Fix display of grouped aliased events 2022-02-10 15:31:36 +01:00
stat-shadow.c
stat.c
stat.h
strbuf.c
strbuf.h
stream.c
stream.h
strfilter.c
strfilter.h
string2.h
string.c
strlist.c
strlist.h
svghelper.c
svghelper.h
symbol_conf.h
symbol_fprintf.c
symbol-elf.c perf symbol: Correct address for bss symbols 2022-09-16 10:53:46 +02:00
symbol-minimal.c
symbol.c perf symbol: Remove arch__symbols__fixup_end() 2022-06-22 14:23:06 +02:00
symbol.h perf symbol: Remove arch__symbols__fixup_end() 2022-06-22 14:23:06 +02:00
symsrc.h
synthetic-events.c
synthetic-events.h
syscalltbl.c
syscalltbl.h
target.c
target.h
term.c
term.h
thread_map.c
thread_map.h
thread-stack.c
thread-stack.h
thread.c
thread.h
time-utils.c
time-utils.h
tool.h
top.c
top.h
topdown.c
topdown.h
trace-event-info.c
trace-event-parse.c
trace-event-read.c
trace-event-scripting.c
trace-event.c
trace-event.h
trigger.h
tsc.c
tsc.h
units.c
units.h
unwind-libdw.c
unwind-libdw.h
unwind-libunwind-local.c
unwind-libunwind.c
unwind.h
usage.c
util.c perf report: Fix memory leaks around perf_tip() 2022-01-04 09:49:06 +01:00
util.h perf report: Fix memory leaks around perf_tip() 2022-01-04 09:49:06 +01:00
values.c
values.h
vdso.c
vdso.h
zlib.c
zstd.c