From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B142747FB03; Sun, 4 Oct 2026 19:51:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791143461; cv=none; b=f+3vpaTNHyDoLA20hDayOxQCzsx0b9EUiFfgb5gA3t1D34pnJBnWvSeCM713UShYMRjdF328c5OPBZEsN12BWdSHeUl86wsktvW/GnuoxLKFcTaJZNxMKuhfNN16N7x/vViVBMAC+tQBTDKi6nVChvSN/XM7m6pe/xnYCrkRMPw= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791143461; c=relaxed/simple; bh=9+lboIMu86IHuKDIB4AmMWUtDL1j6V6/Jd2xiyAw/6g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PrSE0nnzyP1zVpqChrKC5+JNqao4Bl1lBo6ozCBzQyM5r1u5BN8i15B/fqa++9rstV3venEGaBOnuu8iRNAD5QaBxrrvSf2C1ldC9E3Yor7Z2+cXeyX8ocTZQ7mUNGvGHgwrY8JR/uW0vVRkPfvXS3/L6xCx95RVK/SfvHAUVkA= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=AdjfB4CW; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="AdjfB4CW" Received: by smtp.kernel.org (Postfix) with ESMTPS id 44A54C4AF13; Sun, 4 Oct 2026 19:51:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1791143461; bh=9+lboIMu86IHuKDIB4AmMWUtDL1j6V6/Jd2xiyAw/6g=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=AdjfB4CWpz3vvF23r02cn7cCelbDMF/34vJ/XTMqCTN5O9uwRZouD0aDQvsB/LRs2 qtpjXJoJ4PuIHAhidBreTntiprbllUB+4lz4vdecp2fxWAzwmTeRLYy3up3ROiLq36 66DmVEI6W2HEdrtuDMYA6idH8Th0uvpJYyEgZDkh9fq5t3oVfbWhMSTHP/jm3wOodq S1CRHIGbvxX/rgGtBqlz1eNu4QDvUW0Of6JOkYs8tdTtvYgp0/jeQJ+gvqpHhly6/j ef4aJi/2RnP0DNXjAlpBN41Z+uy+diftHIXYcxhxAFsf4ZXz41gUXNlYMcwuBDhIpY 79N8F1QGK98xw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1FA60CA5FEC; Sun, 4 Oct 2026 19:51:01 +0000 (UTC) From: Lawrence Lin via B4 Relay Date: Sun, 04 Oct 2026 14:51:00 -0500 Subject: [PATCH v2 1/2] module: Add module_kallsyms_on_each_addr() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20261004-ftrace-mod-bsearch-v2-1-c1de73e72e73@gmail.com> References: <20261004-ftrace-mod-bsearch-v2-0-c1de73e72e73@gmail.com> In-Reply-To: <20261004-ftrace-mod-bsearch-v2-0-c1de73e72e73@gmail.com> To: Steven Rostedt , Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Luis Chamberlain , Petr Pavlu , Daniel Gomez , Sami Tolvanen Cc: Aaron Tomlin , Stanislaw Gruszka , David Laight , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , linux-modules@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, Lawrence Lin X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1791143460; l=4432; i=deduce@gmail.com; s=default; h=from:subject:message-id; bh=k9sVJtA4GmO4insrdVQIsMOHURF52X3DDft+AQtZiU0=; b=cQGCT24hVcy765hus5EhJrrhotjF27h0usQPeS0UBItv3lt2+2iuXfw8/YuN6wxfWXWNh90Oy VlibwCFvldXDjPqAUkHMkXdOglwq5UyKZ9SGkXc6jTb/Jy/K11fwXQO X-Developer-Key: i=deduce@gmail.com; a=ed25519; pk=Ws6hmG/zoco3lMoykbeaYjo9S7a6sDddQY8EALjp9cM= X-Endpoint-Received: by B4 Relay for deduce@gmail.com/default with auth_id=1106 X-Original-From: Lawrence Lin Reply-To: deduce@gmail.com From: Lawrence Lin ftrace needs the addresses of the symbols of a module while the module is still being loaded: ftrace_module_init() runs before complete_formation(), while the module is MODULE_STATE_UNFORMED, and module_kallsyms_on_each_symbol() skips unformed modules. It also needs exactly the symbols that find_kallsyms_symbol() may resolve an address to, so that it agrees with kallsyms_lookup(). Factor the symbol filter of find_kallsyms_symbol() into is_lookup_symbol() and add module_kallsyms_on_each_addr(), which calls a function with the address of each such symbol of a given module. Like find_kallsyms_symbol(), it reads mod->kallsyms under RCU, which add_kallsyms() has set up by then. No functional change to find_kallsyms_symbol(). Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Lawrence Lin --- include/linux/module.h | 10 ++++++++++ kernel/module/kallsyms.c | 44 +++++++++++++++++++++++++++++++++++--------- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/include/linux/module.h b/include/linux/module.h index 96cc98568eea..8b1c06d1118c 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -971,6 +971,10 @@ unsigned long module_kallsyms_lookup_name(const char *name); unsigned long find_kallsyms_symbol_value(struct module *mod, const char *name); +void module_kallsyms_on_each_addr(struct module *mod, + void (*fn)(void *, unsigned long), + void *data); + #else /* CONFIG_MODULES && CONFIG_KALLSYMS */ static inline int module_kallsyms_on_each_symbol(const char *modname, @@ -1014,6 +1018,12 @@ static inline unsigned long find_kallsyms_symbol_value(struct module *mod, return 0; } +static inline void module_kallsyms_on_each_addr(struct module *mod, + void (*fn)(void *, unsigned long), + void *data) +{ +} + #endif /* CONFIG_MODULES && CONFIG_KALLSYMS */ /* Define __free(module_put) macro for struct module *. */ diff --git a/kernel/module/kallsyms.c b/kernel/module/kallsyms.c index f23126d804b2..bccee4b8294c 100644 --- a/kernel/module/kallsyms.c +++ b/kernel/module/kallsyms.c @@ -246,6 +246,18 @@ static const char *kallsyms_symbol_name(struct mod_kallsyms *kallsyms, unsigned return kallsyms->strtab + kallsyms->symtab[symnum].st_name; } +/* + * Whether find_kallsyms_symbol() may resolve an address to symbol @symnum. + * Unnamed symbols are ignored: they're uninformative and inserted at a whim. + */ +static bool is_lookup_symbol(struct mod_kallsyms *kallsyms, unsigned int symnum) +{ + const char *name = kallsyms_symbol_name(kallsyms, symnum); + + return kallsyms->symtab[symnum].st_shndx != SHN_UNDEF && + *name != '\0' && !is_mapping_symbol(name); +} + /* * Given a module and address, find the corresponding symbol and return its name * while providing its size and offset if needed. @@ -286,15 +298,7 @@ static const char *find_kallsyms_symbol(struct module *mod, const Elf_Sym *sym = &kallsyms->symtab[i]; unsigned long thisval = kallsyms_symbol_value(sym); - if (sym->st_shndx == SHN_UNDEF) - continue; - - /* - * We ignore unnamed symbols: they're uninformative - * and inserted at a whim. - */ - if (*kallsyms_symbol_name(kallsyms, i) == '\0' || - is_mapping_symbol(kallsyms_symbol_name(kallsyms, i))) + if (!is_lookup_symbol(kallsyms, i)) continue; if (thisval <= addr && thisval > bestval) { @@ -458,6 +462,28 @@ unsigned long find_kallsyms_symbol_value(struct module *mod, const char *name) return __find_kallsyms_symbol_value(mod, name); } +/* + * Call @fn with the address of each symbol of @mod that find_kallsyms_symbol() + * may resolve an address to. Unlike module_kallsyms_on_each_symbol(), this + * also works while @mod is still being loaded. + */ +void module_kallsyms_on_each_addr(struct module *mod, + void (*fn)(void *, unsigned long), + void *data) +{ + struct mod_kallsyms *kallsyms; + unsigned int i; + + guard(rcu)(); + kallsyms = rcu_dereference(mod->kallsyms); + + /* ELF starts real symbols at 1. */ + for (i = 1; i < kallsyms->num_symtab; i++) { + if (is_lookup_symbol(kallsyms, i)) + fn(data, kallsyms_symbol_value(&kallsyms->symtab[i])); + } +} + int module_kallsyms_on_each_symbol(const char *modname, int (*fn)(void *, const char *, unsigned long), void *data) -- 2.55.0