Re: [PATCH 3/5] perf tools: Fallback to initial kernel map properly

From: Ian Rogers
Date: Tue Dec 02 2025 - 15:55:37 EST


On Tue, Dec 2, 2025 at 12:16 AM Namhyung Kim <namhyung@xxxxxxxxxx> wrote:
>
> In maps__split_kallsyms(), it assumes new kernel map when it finds a
> symbol without module after any module and the initial kernel map has
> some symbols. Because it expects modules are out of the kernel map so
> modules should not have symbols in the kernel map.
>
> For example, the following memory map shows symbols and maps. Any
> symbols in the module 1 area will go to the module 1. The main kernel
> map starts at 0xffffffffbc200000. But if any symbol has a module
> between the symbols in that area, next symbols after 0xffffffffbd008000
> will generate new kernel maps like [kernel].1.
>
> kernel address | |
> | |
> 0xffffffffc0000000 |---------------------|
> | (symbols) |
> | ... | <--- [kernel].N
> 0xffffffffbc400000 |---------------------|
> | (symbols) |
> | module 2 | <--- bad?
> 0xffffffffbc380000 |---------------------|
> | ... |
> | (symbols) |
> | [kernel.kallsyms] | <--- initial map
> 0xffffffffbc200000 |---------------------|
> | |
> | |
> 0xffffffffabcde000 |---------------------|
> | (symbols) |
> | module 1 |
> 0xffffffffabcd0000 |---------------------|
>
> This is very fragile when the module has a symbol that falls into the
> main kernel map for some reason. My system has a livepatch module with
> such symbols. And it created a lot of new kernel maps after those
> symbols. But the symbol may have broken addresses and the later symbols
> can still be found in the initial kernel map.
>
> Let's check the symbol address in the initial map and use it if found.
>
> Signed-off-by: Namhyung Kim <namhyung@xxxxxxxxxx>
> ---
> tools/perf/util/symbol.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
> index 8eea49c50453d13a..b533fbf17a8b19a3 100644
> --- a/tools/perf/util/symbol.c
> +++ b/tools/perf/util/symbol.c
> @@ -951,7 +951,8 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta,
> pos->end -= delta;
> }
>
> - if (count == 0) {
> + if (map__start(initial_map) <= (pos->start + delta) &&
> + (pos->start + delta) < map__end(initial_map)) {

Reviewed-by: Ian Rogers <irogers@xxxxxxxxxx>
nit: it looks a little clunky to subtract off delta above, but then
add it on again here.

Thanks,
Ian

> map__zput(curr_map);
> curr_map = map__get(initial_map);
> goto add_symbol;
> --
> 2.52.0.158.g65b55ccf14-goog
>