* [PATCH] perf symbols: Fix module symbol resolution for non-zero .text sh_addr
@ 2026-03-23 15:58 Chuck Lever
2026-03-24 11:07 ` Thomas Richter
0 siblings, 1 reply; 2+ messages in thread
From: Chuck Lever @ 2026-03-23 15:58 UTC (permalink / raw)
To: peterz, mingo, acme, namhyung; +Cc: linux-perf-users, Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
When perf resolves symbols from kernel module ELF files (ET_REL),
it converts symbol addresses to file offsets so that sample IPs
can be matched to the correct symbol. The conversion adjusts each
symbol's st_value:
sym->st_value -= shdr->sh_addr - shdr->sh_offset;
For vmlinux (ET_EXEC), st_value is a virtual address and sh_addr
is the section's virtual base, so subtracting sh_addr and adding
sh_offset correctly yields a file offset.
For kernel modules (ET_REL), st_value is a section-relative
offset. The module loader ignores sh_addr entirely and places
symbols at module_base + st_value. Converting to file offset
requires only adding sh_offset; subtracting sh_addr introduces an
error equal to sh_addr bytes.
When .text has sh_addr == 0 -- the historical norm for simple
modules -- both formulas produce the same result and the bug is
latent. As modules gain more metadata sections before .text (.note,
.static_call.text, etc.), the linker assigns .text a non-zero
sh_addr, exposing the defect. For example, nfsd.ko on this kernel
has sh_addr=0xa80, kvm-intel.ko has sh_addr=0x1e90.
The effect is that all .text symbols in affected modules
shift by sh_addr bytes relative to sample IPs, causing perf
report to attribute samples to incorrect, nearby symbols. This
was observed as 13% of LLC-load-miss samples misattributed
to nfsd_file_get_dio_attrs when the actual hot function was
nfsd_cache_lookup, approximately 0xa80 bytes away in the symbol
table.
Use the existing dso__rel() flag (already set for ET_REL modules)
to select the correct adjustment: add sh_offset for ET_REL,
subtract (sh_addr - sh_offset) for ET_EXEC/ET_DYN.
Fixes: 0131c4ec794a ("perf tools: Make it possible to read object code from kernel modules")
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
tools/perf/util/symbol-elf.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 76912c62b6a0..968e269d9be1 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -1356,8 +1356,12 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
char dso_name[PATH_MAX];
/* Adjust symbol to map to file offset */
- if (adjust_kernel_syms)
- sym->st_value -= shdr->sh_addr - shdr->sh_offset;
+ if (adjust_kernel_syms) {
+ if (dso__rel(dso))
+ sym->st_value += shdr->sh_offset;
+ else
+ sym->st_value -= shdr->sh_addr - shdr->sh_offset;
+ }
if (strcmp(section_name, (dso__short_name(curr_dso) + dso__short_name_len(dso))) == 0)
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] perf symbols: Fix module symbol resolution for non-zero .text sh_addr
2026-03-23 15:58 [PATCH] perf symbols: Fix module symbol resolution for non-zero .text sh_addr Chuck Lever
@ 2026-03-24 11:07 ` Thomas Richter
0 siblings, 0 replies; 2+ messages in thread
From: Thomas Richter @ 2026-03-24 11:07 UTC (permalink / raw)
To: Chuck Lever, peterz, mingo, acme, namhyung; +Cc: linux-perf-users, Chuck Lever
On 3/23/26 16:58, Chuck Lever wrote:
> From: Chuck Lever <chuck.lever@oracle.com>
>
> When perf resolves symbols from kernel module ELF files (ET_REL),
> it converts symbol addresses to file offsets so that sample IPs
> can be matched to the correct symbol. The conversion adjusts each
> symbol's st_value:
>
> sym->st_value -= shdr->sh_addr - shdr->sh_offset;
>
> For vmlinux (ET_EXEC), st_value is a virtual address and sh_addr
> is the section's virtual base, so subtracting sh_addr and adding
> sh_offset correctly yields a file offset.
>
> For kernel modules (ET_REL), st_value is a section-relative
> offset. The module loader ignores sh_addr entirely and places
> symbols at module_base + st_value. Converting to file offset
> requires only adding sh_offset; subtracting sh_addr introduces an
> error equal to sh_addr bytes.
>
> When .text has sh_addr == 0 -- the historical norm for simple
> modules -- both formulas produce the same result and the bug is
> latent. As modules gain more metadata sections before .text (.note,
> .static_call.text, etc.), the linker assigns .text a non-zero
> sh_addr, exposing the defect. For example, nfsd.ko on this kernel
> has sh_addr=0xa80, kvm-intel.ko has sh_addr=0x1e90.
>
> The effect is that all .text symbols in affected modules
> shift by sh_addr bytes relative to sample IPs, causing perf
> report to attribute samples to incorrect, nearby symbols. This
> was observed as 13% of LLC-load-miss samples misattributed
> to nfsd_file_get_dio_attrs when the actual hot function was
> nfsd_cache_lookup, approximately 0xa80 bytes away in the symbol
> table.
>
> Use the existing dso__rel() flag (already set for ET_REL modules)
> to select the correct adjustment: add sh_offset for ET_REL,
> subtract (sh_addr - sh_offset) for ET_EXEC/ET_DYN.
>
> Fixes: 0131c4ec794a ("perf tools: Make it possible to read object code from kernel modules")
> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
> ---
> tools/perf/util/symbol-elf.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
> index 76912c62b6a0..968e269d9be1 100644
> --- a/tools/perf/util/symbol-elf.c
> +++ b/tools/perf/util/symbol-elf.c
> @@ -1356,8 +1356,12 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
> char dso_name[PATH_MAX];
>
> /* Adjust symbol to map to file offset */
> - if (adjust_kernel_syms)
> - sym->st_value -= shdr->sh_addr - shdr->sh_offset;
> + if (adjust_kernel_syms) {
> + if (dso__rel(dso))
> + sym->st_value += shdr->sh_offset;
> + else
> + sym->st_value -= shdr->sh_addr - shdr->sh_offset;
> + }
>
> if (strcmp(section_name, (dso__short_name(curr_dso) + dso__short_name_len(dso))) == 0)
> return 0;
For s390
Tested-by: Thomas Richter <tmricht@linux.ibm.com>
--
Thomas Richter, Dept 3303, IBM s390 Linux Development, Boeblingen, Germany
--
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Wolfgang Wendt
Geschäftsführung: David Faller
Sitz der Gesellschaft: Böblingen / Registergericht: Amtsgericht Stuttgart, HRB 243294
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-03-24 11:07 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-23 15:58 [PATCH] perf symbols: Fix module symbol resolution for non-zero .text sh_addr Chuck Lever
2026-03-24 11:07 ` Thomas Richter
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox