* [PATCH v2] perf: Extract is_mapping_symbol() helper for kernel mapping symbol filtering
@ 2026-05-06 7:38 Rui Qi
2026-05-06 10:43 ` sashiko-bot
2026-05-07 7:11 ` [PATCH v3] perf: Add " Rui Qi
0 siblings, 2 replies; 6+ messages in thread
From: Rui Qi @ 2026-05-06 7:38 UTC (permalink / raw)
To: linux-perf-users
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Rui Qi
The perf tool currently has ad-hoc logic to filter out ELF mapping
symbols scattered across multiple files and architectures. ARM,
AArch64 and RISC-V each have their own inline checks in
dso__load_sym_internal(), and kallsym processing in map__process_kallsym_symbol()
has yet another check for ARM module symbols.
This is fragile: adding support for a new architecture or adjusting
which prefixes are considered mapping symbols requires touching
multiple places, and it is easy for the checks to diverge. It also
does not match the kernel's own is_mapping_symbol() logic, which
additionally covers x86 local symbols ('.L*' and 'L0*').
Introduce a single is_mapping_symbol() inline helper in symbol.h and
convert kernel symbol handling to use it. The helper covers the
existing '$' prefix used by ARM, AArch64 and RISC-V, and also adds
the x86 local symbol prefixes so that perf stays consistent with
the kernel.
Signed-off-by: Rui Qi <qirui.001@bytedance.com>
---
Changes in v2:
- Only apply is_mapping_symbol() filtering to kernel symbols (kallsyms
and ksymbol events), not to user-space symbols from ELF files,
BFD libraries, or perf map files. This avoids incorrectly
discarding valid user-space function names that start with '$',
which is a legal character in identifiers for many languages
(e.g., Java, Scala) and compilers (GCC).
- Move the mapping symbol check in machine__process_ksymbol_register()
to the beginning of the function, before any map/dso allocation
or insertion, to avoid leaving empty maps in the kernel map tree.
Link (v1): https://lore.kernel.org/all/20260504090609.1801880-1-qirui.001@bytedance.com/
tools/perf/util/machine.c | 8 +++++++-
tools/perf/util/symbol.c | 4 ++--
tools/perf/util/symbol.h | 15 +++++++++++++++
3 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index e76f8c86e62a..e0dcf8bfb896 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -729,9 +729,15 @@ static int machine__process_ksymbol_register(struct machine *machine,
{
struct symbol *sym;
struct dso *dso = NULL;
- struct map *map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr);
+ struct map *map;
int err = 0;
+ /* Ignore mapping symbols in ksymbol events - check early before any state mutation */
+ if (is_mapping_symbol(event->ksymbol.name))
+ return 0;
+
+ map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr);
+
if (!map) {
dso = dso__new(event->ksymbol.name);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index fcaeeddbbb6b..af03b16c17c6 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -770,8 +770,8 @@ static int map__process_kallsym_symbol(void *arg, const char *name,
if (!symbol_type__filter(type))
return 0;
- /* Ignore local symbols for ARM modules */
- if (name[0] == '$')
+ /* Ignore mapping symbols in kallsyms */
+ if (is_mapping_symbol(name))
return 0;
/*
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index bd6eb90c8668..27fa1b43e6f1 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -28,6 +28,21 @@ struct maps;
struct option;
struct build_id;
+/*
+ * Ignore kernel mapping symbols, matching kernel is_mapping_symbol() logic.
+ * This checks for '$' prefix (used by ARM, AArch64, RISC-V) and
+ * x86 local symbol prefixes (.L* and L0*).
+ * Only use this for kernel symbols (kallsyms, ksymbol events).
+ */
+static inline bool is_mapping_symbol(const char *str)
+{
+ if (str[0] == '.' && str[1] == 'L')
+ return true;
+ if (str[0] == 'L' && str[1] == '0')
+ return true;
+ return str[0] == '$';
+}
+
/*
* libelf 0.8.x and earlier do not support ELF_C_READ_MMAP;
* for newer versions we can use mmap to reduce memory usage:
--
2.20.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH v2] perf: Extract is_mapping_symbol() helper for kernel mapping symbol filtering 2026-05-06 7:38 [PATCH v2] perf: Extract is_mapping_symbol() helper for kernel mapping symbol filtering Rui Qi @ 2026-05-06 10:43 ` sashiko-bot 2026-05-07 6:27 ` Rui Qi 2026-05-07 7:11 ` [PATCH v3] perf: Add " Rui Qi 1 sibling, 1 reply; 6+ messages in thread From: sashiko-bot @ 2026-05-06 10:43 UTC (permalink / raw) To: Rui Qi; +Cc: linux-perf-users Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider: - [High] Asymmetric mapping symbol filtering leads to map/symbol deletion during ksymbol unregistration. - [Medium] Incomplete refactoring leaves ELF mapping symbol logic fragile and inconsistent. -- commit f27956b5bf680b8ef41ba119f6dc5cedae4567f5 Author: Rui Qi <qirui.001@bytedance.com> perf: Extract is_mapping_symbol() helper for kernel mapping symbol filtering This patch introduces an is_mapping_symbol() inline helper to consolidate logic for filtering out ELF mapping symbols across architectures. It also adds the helper to machine__process_ksymbol_register() and map__process_kallsym_symbol(). > The perf tool currently has ad-hoc logic to filter out ELF mapping > symbols scattered across multiple files and architectures. ARM, > AArch64 and RISC-V each have their own inline checks in > dso__load_sym_internal(), and kallsym processing in map__process_kallsym_symbol() > has yet another check for ARM module symbols. > > This is fragile: adding support for a new architecture or adjusting > which prefixes are considered mapping symbols requires touching > multiple places, and it is easy for the checks to diverge. It also > does not match the kernel's own is_mapping_symbol() logic, which > additionally covers x86 local symbols ('.L*' and 'L0*'). This commit message claims to convert dso__load_sym_internal() to use the new helper. However, this patch does not modify dso__load_sym_internal() in tools/perf/util/symbol-elf.c at all, leaving the scattered inline checks untouched. Because x86 local symbols (.L*) were added to the new helper, does this omission introduce a new inconsistency where kallsyms parsing will correctly filter x86 .L* symbols, but kernel module parsing via ELF (.ko) will not? > diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c > index e76f8c86e62a6..e0dcf8bfb896e 100644 > --- a/tools/perf/util/machine.c > +++ b/tools/perf/util/machine.c > @@ -729,9 +729,15 @@ static int machine__process_ksymbol_register(struct machine *machine, > { > struct symbol *sym; > struct dso *dso = NULL; > - struct map *map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr); > + struct map *map; > int err = 0; > > + /* Ignore mapping symbols in ksymbol events - check early before any state mutation */ > + if (is_mapping_symbol(event->ksymbol.name)) > + return 0; If a PERF_RECORD_KSYMBOL event arrives with the UNREGISTER flag, machine__process_ksymbol() routes it to machine__process_ksymbol_unregister(). Because machine__process_ksymbol_unregister() does not have the same is_mapping_symbol() filter, could maps__find() return the enclosing map (such as the BPF JIT map or a loaded kernel module's map) that covers the mapping symbol's address? tools/perf/util/machine.c:machine__process_ksymbol_unregister() { ... map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr); if (!map) return 0; if (!RC_CHK_EQUAL(map, machine->vmlinux_map)) maps__remove(machine__kernel_maps(machine), map); ... } If so, will the unregister path incorrectly call maps__remove() on that parent map, prematurely destroying legitimate tracking state and breaking symbol resolution for subsequent samples in that memory region? -- Sashiko AI review · https://sashiko.dev/#/patchset/20260506073820.2419087-1-qirui.001@bytedance.com?part=1 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] perf: Extract is_mapping_symbol() helper for kernel mapping symbol filtering 2026-05-06 10:43 ` sashiko-bot @ 2026-05-07 6:27 ` Rui Qi 0 siblings, 0 replies; 6+ messages in thread From: Rui Qi @ 2026-05-07 6:27 UTC (permalink / raw) To: sashiko; +Cc: linux-perf-users On 5/6/26 6:43 PM, sashiko-bot@kernel.org wrote: > Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider: > - [High] Asymmetric mapping symbol filtering leads to map/symbol deletion during ksymbol unregistration. > - [Medium] Incomplete refactoring leaves ELF mapping symbol logic fragile and inconsistent. > -- > > commit f27956b5bf680b8ef41ba119f6dc5cedae4567f5 > Author: Rui Qi <qirui.001@bytedance.com> > > perf: Extract is_mapping_symbol() helper for kernel mapping symbol filtering > > This patch introduces an is_mapping_symbol() inline helper to consolidate > logic for filtering out ELF mapping symbols across architectures. It also > adds the helper to machine__process_ksymbol_register() and > map__process_kallsym_symbol(). > >> The perf tool currently has ad-hoc logic to filter out ELF mapping >> symbols scattered across multiple files and architectures. ARM, >> AArch64 and RISC-V each have their own inline checks in >> dso__load_sym_internal(), and kallsym processing in map__process_kallsym_symbol() >> has yet another check for ARM module symbols. >> >> This is fragile: adding support for a new architecture or adjusting >> which prefixes are considered mapping symbols requires touching >> multiple places, and it is easy for the checks to diverge. It also >> does not match the kernel's own is_mapping_symbol() logic, which >> additionally covers x86 local symbols ('.L*' and 'L0*'). > > This commit message claims to convert dso__load_sym_internal() to use the > new helper. However, this patch does not modify dso__load_sym_internal() > in tools/perf/util/symbol-elf.c at all, leaving the scattered inline checks > untouched. > > Because x86 local symbols (.L*) were added to the new helper, does this > omission introduce a new inconsistency where kallsyms parsing will correctly > filter x86 .L* symbols, but kernel module parsing via ELF (.ko) will not? > I believe this is not a bug. The is_mapping_symbol() helper is explicitly documented as kernel-only: /* * Ignore kernel mapping symbols, matching kernel is_mapping_symbol() logic. * ... * Only use this for kernel symbols (kallsyms, ksymbol events). */ The dso__load_sym_internal() function handles both kernel and userspace symbols. Applying is_mapping_symbol() there would incorrectly filter out userspace .L* and L0* symbols. However, I noticed that kernel modules could also benefit from filtering x86 .L* symbols. I've added the following in dso__load_sym_internal() to handle this case: /* * For kernel modules, also reject x86 local symbols (.L* and L0*) * to match the kernel's is_mapping_symbol() logic and kallsyms * parsing behavior. */ if (kmodule && is_mapping_symbol(elf_name)) continue; This ensures: 1. Only kernel modules are filtered (kmodule == true) 2. Userspace symbols are not affected 3. The existing is_mapping_symbol() helper is reused >> diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c >> index e76f8c86e62a6..e0dcf8bfb896e 100644 >> --- a/tools/perf/util/machine.c >> +++ b/tools/perf/util/machine.c >> @@ -729,9 +729,15 @@ static int machine__process_ksymbol_register(struct machine *machine, >> { >> struct symbol *sym; >> struct dso *dso = NULL; >> - struct map *map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr); >> + struct map *map; >> int err = 0; >> >> + /* Ignore mapping symbols in ksymbol events - check early before any state mutation */ >> + if (is_mapping_symbol(event->ksymbol.name)) >> + return 0; > > If a PERF_RECORD_KSYMBOL event arrives with the UNREGISTER flag, > machine__process_ksymbol() routes it to machine__process_ksymbol_unregister(). > > Because machine__process_ksymbol_unregister() does not have the same > is_mapping_symbol() filter, could maps__find() return the enclosing map > (such as the BPF JIT map or a loaded kernel module's map) that covers the > mapping symbol's address? > > tools/perf/util/machine.c:machine__process_ksymbol_unregister() { > ... > map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr); > if (!map) > return 0; > > if (!RC_CHK_EQUAL(map, machine->vmlinux_map)) > maps__remove(machine__kernel_maps(machine), map); > ... > } > > If so, will the unregister path incorrectly call maps__remove() on that > parent map, prematurely destroying legitimate tracking state and breaking > symbol resolution for subsequent samples in that memory region? > You are absolutely right. The is_mapping_symbol() check is missing in machine__process_ksymbol_unregister(). This could indeed cause the unregister path to incorrectly remove a parent map when a mapping symbol address falls within an existing map range. I will fix this by adding the same filter to machine__process_ksymbol_unregister(): static int machine__process_ksymbol_unregister(struct machine *machine, union perf_event *event,struct perf_sample *sample __maybe_unused) { struct symbol *sym; struct map *map; /* Ignore mapping symbols in ksymbol events */ if (is_mapping_symbol(event->ksymbol.name)) return 0; map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr); ... } I will send a v3 with these fixes. Thanks, Rui Qi ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3] perf: Add is_mapping_symbol() helper for kernel mapping symbol filtering 2026-05-06 7:38 [PATCH v2] perf: Extract is_mapping_symbol() helper for kernel mapping symbol filtering Rui Qi 2026-05-06 10:43 ` sashiko-bot @ 2026-05-07 7:11 ` Rui Qi 2026-05-07 15:23 ` Ian Rogers 2026-05-07 20:38 ` sashiko-bot 1 sibling, 2 replies; 6+ messages in thread From: Rui Qi @ 2026-05-07 7:11 UTC (permalink / raw) To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim Cc: Mark Rutland, Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter, James Clark, linux-perf-users, linux-kernel, Rui Qi The perf tool currently has ad-hoc logic to filter out ELF mapping symbols scattered across multiple files. ARM, AArch64 and RISC-V each have their own inline checks in dso__load_sym_internal(), and kallsym processing has yet another check for ARM module symbols. This is fragile: adding support for a new architecture or adjusting which prefixes are considered mapping symbols requires touching multiple places, and it is easy for the checks to diverge. It also does not match the kernel's own is_mapping_symbol() logic, which additionally covers x86 local symbols (".L*" and "L0*"). Introduce a single is_mapping_symbol() inline helper in symbol.h and convert all kernel symbol handling to use it. The helper covers the existing "$" prefix used by ARM, AArch64 and RISC-V, and also adds the x86 local symbol prefixes so that perf stays consistent with the kernel. Signed-off-by: Rui Qi <qirui.001@bytedance.com> --- Changes in v3: - Add is_mapping_symbol() check for kernel modules in dso__load_sym_internal() - Add is_mapping_symbol() check in machine__process_ksymbol_unregister() Link (v2): https://lore.kernel.org/all/20260506073820.2419087-1-qirui.001@bytedance.com/ Changes in v2: - Only apply is_mapping_symbol() filtering to kernel symbols (kallsyms and ksymbol events), not to user-space symbols from ELF files, BFD libraries, or perf map files. This avoids incorrectly discarding valid user-space function names that start with '$', which is a legal character in identifiers for many languages (e.g., Java, Scala) and compilers (GCC). - Move the mapping symbol check in machine__process_ksymbol_register() to the beginning of the function, before any map/dso allocation or insertion, to avoid leaving empty maps in the kernel map tree. Link (v1): https://lore.kernel.org/all/20260504090609.1801880-1-qirui.001@bytedance.com/ --- tools/perf/util/machine.c | 12 +++++++++++- tools/perf/util/symbol-elf.c | 8 ++++++++ tools/perf/util/symbol.c | 4 ++-- tools/perf/util/symbol.h | 15 +++++++++++++++ 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index e76f8c86e62a..4e33ba06111d 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -729,9 +729,15 @@ static int machine__process_ksymbol_register(struct machine *machine, { struct symbol *sym; struct dso *dso = NULL; - struct map *map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr); + struct map *map; int err = 0; + /* Ignore mapping symbols in ksymbol events - check early before any state mutation */ + if (is_mapping_symbol(event->ksymbol.name)) + return 0; + + map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr); + if (!map) { dso = dso__new(event->ksymbol.name); @@ -790,6 +796,10 @@ static int machine__process_ksymbol_unregister(struct machine *machine, struct symbol *sym; struct map *map; + /* Ignore mapping symbols in ksymbol events */ + if (is_mapping_symbol(event->ksymbol.name)) + return 0; + map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr); if (!map) return 0; diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 7afa8a117139..6b12508ea58d 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1607,6 +1607,14 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss, continue; } + /* + * For kernel modules, also reject x86 local symbols (.L* and L0*) + * to match the kernel's is_mapping_symbol() logic and kallsyms + * parsing behavior. + */ + if (kmodule && is_mapping_symbol(elf_name)) + continue; + if (runtime_ss->opdsec && sym.st_shndx == runtime_ss->opdidx) { u32 offset = sym.st_value - syms_ss->opdshdr.sh_addr; u64 *opd = opddata->d_buf + offset; diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index fcaeeddbbb6b..af03b16c17c6 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -770,8 +770,8 @@ static int map__process_kallsym_symbol(void *arg, const char *name, if (!symbol_type__filter(type)) return 0; - /* Ignore local symbols for ARM modules */ - if (name[0] == '$') + /* Ignore mapping symbols in kallsyms */ + if (is_mapping_symbol(name)) return 0; /* diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index bd6eb90c8668..27fa1b43e6f1 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -28,6 +28,21 @@ struct maps; struct option; struct build_id; +/* + * Ignore kernel mapping symbols, matching kernel is_mapping_symbol() logic. + * This checks for '$' prefix (used by ARM, AArch64, RISC-V) and + * x86 local symbol prefixes (.L* and L0*). + * Only use this for kernel symbols (kallsyms, ksymbol events). + */ +static inline bool is_mapping_symbol(const char *str) +{ + if (str[0] == '.' && str[1] == 'L') + return true; + if (str[0] == 'L' && str[1] == '0') + return true; + return str[0] == '$'; +} + /* * libelf 0.8.x and earlier do not support ELF_C_READ_MMAP; * for newer versions we can use mmap to reduce memory usage: -- 2.20.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v3] perf: Add is_mapping_symbol() helper for kernel mapping symbol filtering 2026-05-07 7:11 ` [PATCH v3] perf: Add " Rui Qi @ 2026-05-07 15:23 ` Ian Rogers 2026-05-07 20:38 ` sashiko-bot 1 sibling, 0 replies; 6+ messages in thread From: Ian Rogers @ 2026-05-07 15:23 UTC (permalink / raw) To: Rui Qi Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa, Adrian Hunter, James Clark, linux-perf-users, linux-kernel On Thu, May 7, 2026 at 12:11 AM Rui Qi <qirui.001@bytedance.com> wrote: > > The perf tool currently has ad-hoc logic to filter out ELF mapping > symbols scattered across multiple files. ARM, AArch64 and RISC-V each > have their own inline checks in dso__load_sym_internal(), and kallsym > processing has yet another check for ARM module symbols. > > This is fragile: adding support for a new architecture or adjusting > which prefixes are considered mapping symbols requires touching > multiple places, and it is easy for the checks to diverge. It also > does not match the kernel's own is_mapping_symbol() logic, which > additionally covers x86 local symbols (".L*" and "L0*"). > > Introduce a single is_mapping_symbol() inline helper in symbol.h and > convert all kernel symbol handling to use it. The helper covers the > existing "$" prefix used by ARM, AArch64 and RISC-V, and also adds > the x86 local symbol prefixes so that perf stays consistent with > the kernel. > > Signed-off-by: Rui Qi <qirui.001@bytedance.com> > --- > Changes in v3: > - Add is_mapping_symbol() check for kernel modules in dso__load_sym_internal() > - Add is_mapping_symbol() check in machine__process_ksymbol_unregister() > > Link (v2): https://lore.kernel.org/all/20260506073820.2419087-1-qirui.001@bytedance.com/ > > Changes in v2: > - Only apply is_mapping_symbol() filtering to kernel symbols (kallsyms > and ksymbol events), not to user-space symbols from ELF files, > BFD libraries, or perf map files. This avoids incorrectly > discarding valid user-space function names that start with '$', > which is a legal character in identifiers for many languages > (e.g., Java, Scala) and compilers (GCC). > - Move the mapping symbol check in machine__process_ksymbol_register() > to the beginning of the function, before any map/dso allocation > or insertion, to avoid leaving empty maps in the kernel map tree. > > Link (v1): https://lore.kernel.org/all/20260504090609.1801880-1-qirui.001@bytedance.com/ > --- > tools/perf/util/machine.c | 12 +++++++++++- > tools/perf/util/symbol-elf.c | 8 ++++++++ > tools/perf/util/symbol.c | 4 ++-- > tools/perf/util/symbol.h | 15 +++++++++++++++ > 4 files changed, 36 insertions(+), 3 deletions(-) > > diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c > index e76f8c86e62a..4e33ba06111d 100644 > --- a/tools/perf/util/machine.c > +++ b/tools/perf/util/machine.c > @@ -729,9 +729,15 @@ static int machine__process_ksymbol_register(struct machine *machine, > { > struct symbol *sym; > struct dso *dso = NULL; > - struct map *map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr); > + struct map *map; > int err = 0; > > + /* Ignore mapping symbols in ksymbol events - check early before any state mutation */ > + if (is_mapping_symbol(event->ksymbol.name)) > + return 0; > + > + map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr); > + > if (!map) { > dso = dso__new(event->ksymbol.name); > > @@ -790,6 +796,10 @@ static int machine__process_ksymbol_unregister(struct machine *machine, > struct symbol *sym; > struct map *map; > > + /* Ignore mapping symbols in ksymbol events */ > + if (is_mapping_symbol(event->ksymbol.name)) > + return 0; > + > map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr); > if (!map) > return 0; > diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c > index 7afa8a117139..6b12508ea58d 100644 > --- a/tools/perf/util/symbol-elf.c > +++ b/tools/perf/util/symbol-elf.c > @@ -1607,6 +1607,14 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss, > continue; > } > > + /* > + * For kernel modules, also reject x86 local symbols (.L* and L0*) > + * to match the kernel's is_mapping_symbol() logic and kallsyms > + * parsing behavior. > + */ > + if (kmodule && is_mapping_symbol(elf_name)) > + continue; > + > if (runtime_ss->opdsec && sym.st_shndx == runtime_ss->opdidx) { > u32 offset = sym.st_value - syms_ss->opdshdr.sh_addr; > u64 *opd = opddata->d_buf + offset; > diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c > index fcaeeddbbb6b..af03b16c17c6 100644 > --- a/tools/perf/util/symbol.c > +++ b/tools/perf/util/symbol.c > @@ -770,8 +770,8 @@ static int map__process_kallsym_symbol(void *arg, const char *name, > if (!symbol_type__filter(type)) > return 0; > > - /* Ignore local symbols for ARM modules */ > - if (name[0] == '$') > + /* Ignore mapping symbols in kallsyms */ > + if (is_mapping_symbol(name)) > return 0; > > /* > diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h > index bd6eb90c8668..27fa1b43e6f1 100644 > --- a/tools/perf/util/symbol.h > +++ b/tools/perf/util/symbol.h > @@ -28,6 +28,21 @@ struct maps; > struct option; > struct build_id; > > +/* > + * Ignore kernel mapping symbols, matching kernel is_mapping_symbol() logic. > + * This checks for '$' prefix (used by ARM, AArch64, RISC-V) and > + * x86 local symbol prefixes (.L* and L0*). > + * Only use this for kernel symbols (kallsyms, ksymbol events). > + */ > +static inline bool is_mapping_symbol(const char *str) Is there a good reference for what is meant by "mapping symbol" ? Would "local symbol" be more appropriate for x86? On ARM it seems the term is well defined: https://developer.arm.com/documentation/dui0803/a/Accessing-and-managing-symbols-with-armlink/About-mapping-symbols I'm wondering if we can make this more intention-revealing. I'm wondering also if we should make the check dependent on the e_machine, so perhaps: ``` static inline is_ignored_kernel_symbol(const char *name, uint16_t e_machine) { if (e_machine == EM_386 || e_machine == EM_X86_64) { /* Local symbols on x86 may start .L or L0. */ return(str[0] == '.' && str[1] == 'L') || (str[0] == 'L' && str[1] == '0'; } /* All other machine types. Assume symbols starting $ are mapping symbols used to denote transitions between different sections of data and code. */ return str[0] == '$'; } ``` I think you can use something like `dso__e_machine` at all call sites to get the ELF machine type for the binary or kernel, but maybe this is overkill. Thanks, Ian > +{ > + if (str[0] == '.' && str[1] == 'L') > + return true; > + if (str[0] == 'L' && str[1] == '0') > + return true; > + return str[0] == '$'; > +} > + > /* > * libelf 0.8.x and earlier do not support ELF_C_READ_MMAP; > * for newer versions we can use mmap to reduce memory usage: > -- > 2.20.1 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3] perf: Add is_mapping_symbol() helper for kernel mapping symbol filtering 2026-05-07 7:11 ` [PATCH v3] perf: Add " Rui Qi 2026-05-07 15:23 ` Ian Rogers @ 2026-05-07 20:38 ` sashiko-bot 1 sibling, 0 replies; 6+ messages in thread From: sashiko-bot @ 2026-05-07 20:38 UTC (permalink / raw) To: Rui Qi; +Cc: linux-perf-users Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider: - [Medium] The commit message claims to replace ad-hoc mapping symbol filtering in `dso__load_sym_internal()` with a single helper, but the existing architecture-specific checks were not removed, resulting in redundant code and a code/commit message mismatch. - [Medium] The new mapping symbol filter in `dso__load_sym_internal()` is strictly gated behind `kmodule`, which incorrectly allows mapping symbols from the main kernel image (`vmlinux`) to bypass the filter. -- commit b0c39fbcfd41cb96be112e1c6d3979a91d527b75 Author: Rui Qi <qirui.001@bytedance.com> perf: Add is_mapping_symbol() helper for kernel mapping symbol filtering This commit introduces a unified is_mapping_symbol() inline helper to consolidate and replace ad-hoc mapping symbol filtering for ARM, AArch64, and RISC-V across the perf tool, while adding x86 local symbol filtering. > perf: Add is_mapping_symbol() helper for kernel mapping symbol filtering > > The perf tool currently has ad-hoc logic to filter out ELF mapping > symbols scattered across multiple files. ARM, AArch64 and RISC-V each > have their own inline checks in dso__load_sym_internal(), and kallsym > processing has yet another check for ARM module symbols. > > This is fragile: adding support for a new architecture or adjusting > which prefixes are considered mapping symbols requires touching > multiple places, and it is easy for the checks to diverge. It also > does not match the kernel's own is_mapping_symbol() logic, which > additionally covers x86 local symbols (".L*" and "L0*"). > > Introduce a single is_mapping_symbol() inline helper in symbol.h and > convert all kernel symbol handling to use it. The commit message states we are replacing the inline checks in dso__load_sym_internal() and converting all kernel symbol handling to use the new helper. However, looking at the resulting code in dso__load_sym_internal(), the old checks are still present: if (ehdr.e_machine == EM_ARM || ehdr.e_machine == EM_AARCH64) { if (elf_name[0] == '$' && strchr("adtx", elf_name[1]) && (elf_name[2] == '\0' || elf_name[2] == '.')) continue; } if (ehdr.e_machine == EM_RISCV) { if (elf_name[0] == '$' && strchr("dx", elf_name[1])) continue; } Should these existing ARM, AArch64, and RISC-V inline checks have been removed to avoid redundant filtering, or was the intention to only apply the new helper to kernel modules while leaving the old checks for user-space binaries? > diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c > index 7afa8a1171396..6b12508ea58dc 100644 > --- a/tools/perf/util/symbol-elf.c > +++ b/tools/perf/util/symbol-elf.c [ ... ] > @@ -1607,6 +1607,14 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss, > continue; > } > > + /* > + * For kernel modules, also reject x86 local symbols (.L* and L0*) > + * to match the kernel's is_mapping_symbol() logic and kallsyms > + * parsing behavior. > + */ > + if (kmodule && is_mapping_symbol(elf_name)) > + continue; > + When perf loads the main kernel image via dso__load_vmlinux(), it calls dso__load_sym() with kmodule = 0. Does gating this check behind kmodule inadvertently bypass the new mapping symbol logic for vmlinux? If so, x86 local symbols might leak into the symbol tables for the main kernel image. Would using dso__kernel(dso) instead of kmodule correctly cover both vmlinux and kernel modules? -- Sashiko AI review · https://sashiko.dev/#/patchset/20260507071103.2772577-1-qirui.001@bytedance.com?part=1 ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-05-07 20:38 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-05-06 7:38 [PATCH v2] perf: Extract is_mapping_symbol() helper for kernel mapping symbol filtering Rui Qi 2026-05-06 10:43 ` sashiko-bot 2026-05-07 6:27 ` Rui Qi 2026-05-07 7:11 ` [PATCH v3] perf: Add " Rui Qi 2026-05-07 15:23 ` Ian Rogers 2026-05-07 20:38 ` sashiko-bot
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox