Skip to content

Commit 4475dff

Browse files
committed
kbuild: fix false-positive modpost warning when all symbols are trimmed
Nathan reports that the mips defconfig emits the following warning: WARNING: modpost: Symbol info of vmlinux is missing. Unresolved symbol check will be entirely skipped. This false-positive happens when CONFIG_TRIM_UNUSED_KSYMS is enabled, but no CONFIG option is set to 'm'. Commit a059047 ("nfs: fix PNFS_FLEXFILE_LAYOUT Kconfig default") turned the last 'm' into 'y' for the mips defconfig, and uncovered this issue. In this case, the module feature itself is enabled, but we have no module to build. As a result, CONFIG_TRIM_UNUSED_KSYMS drops all the instances of EXPORT_SYMBOL. Then, modpost wrongly assumes vmlinux is missing because vmlinux.symvers is empty. (As another false-positive case, you can create a module that does not use any symbol of vmlinux). The current behavior is to entirely suppress the unresolved symbol warnings when vmlinux is missing just because there are too many. I found the origin of this code in the historical git tree. [1] If this is a matter of noisiness, I think modpost can display the first 10 warnings, and the number of suppressed warnings at the end. You will get a bit noisier logs when you run 'make modules' without vmlinux, but such warnings are better to show because you never know the resulting modules are actually loadable or not. This commit changes the following: - If any of input *.symver files is missing, pass -w option to let the module build keep going with warnings instead of errors. - If there are too many (10+) unresolved symbol warnings, show only the first 10, and also the number of suppressed warnings. [1]: https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/?id=1cc0e0529569bf6a94f6d49770aa6d4b599d2c46 Reported-by: Nathan Chancellor <[email protected]> Signed-off-by: Masahiro Yamada <[email protected]>
1 parent 5ab70ff commit 4475dff

File tree

2 files changed

+17
-15
lines changed

2 files changed

+17
-15
lines changed

scripts/Makefile.modpost

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,11 @@ output-symdump := $(KBUILD_EXTMOD)/Module.symvers
9898

9999
endif
100100

101+
existing-input-symdump := $(wildcard $(input-symdump))
102+
101103
# modpost options for modules (both in-kernel and external)
102104
MODPOST += \
103-
$(addprefix -i ,$(wildcard $(input-symdump))) \
105+
$(addprefix -i ,$(existing-input-symdump)) \
104106
$(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) \
105107
$(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N)
106108

@@ -114,6 +116,7 @@ VPATH :=
114116
$(input-symdump):
115117
@echo >&2 'WARNING: Symbol version dump "$@" is missing.'
116118
@echo >&2 ' Modules may not have dependencies or modversions.'
119+
@echo >&2 ' You may get many unresolved symbol warnings.'
117120

118121
ifdef CONFIG_LTO_CLANG
119122
# With CONFIG_LTO_CLANG, .o files might be LLVM bitcode, so we need to run
@@ -134,7 +137,7 @@ endif
134137
modules := $(sort $(shell cat $(MODORDER)))
135138

136139
# KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined symbols
137-
ifneq ($(KBUILD_MODPOST_WARN),)
140+
ifneq ($(KBUILD_MODPOST_WARN)$(filter-out $(existing-input-symdump), $(input-symdump)),)
138141
MODPOST += -w
139142
endif
140143

scripts/mod/modpost.c

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323

2424
/* Are we using CONFIG_MODVERSIONS? */
2525
static int modversions = 0;
26-
/* Warn about undefined symbols? (do so if we have vmlinux) */
27-
static int have_vmlinux = 0;
2826
/* Is CONFIG_MODULE_SRCVERSION_ALL set? */
2927
static int all_versions = 0;
3028
/* If we are modposting external module set to 1 */
@@ -41,6 +39,13 @@ static int allow_missing_ns_imports;
4139

4240
static bool error_occurred;
4341

42+
/*
43+
* Cut off the warnings when there are too many. This typically occurs when
44+
* vmlinux is missing. ('make modules' without building vmlinux.)
45+
*/
46+
#define MAX_UNRESOLVED_REPORTS 10
47+
static unsigned int nr_unresolved;
48+
4449
enum export {
4550
export_plain,
4651
export_gpl,
@@ -177,9 +182,6 @@ static struct module *new_module(const char *modname)
177182
mod->next = modules;
178183
modules = mod;
179184

180-
if (mod->is_vmlinux)
181-
have_vmlinux = 1;
182-
183185
return mod;
184186
}
185187

@@ -2141,7 +2143,7 @@ static void check_exports(struct module *mod)
21412143
const char *basename;
21422144
exp = find_symbol(s->name);
21432145
if (!exp || exp->module == mod) {
2144-
if (have_vmlinux && !s->weak)
2146+
if (!s->weak && nr_unresolved++ < MAX_UNRESOLVED_REPORTS)
21452147
modpost_log(warn_unresolved ? LOG_WARN : LOG_ERROR,
21462148
"\"%s\" [%s.ko] undefined!\n",
21472149
s->name, mod->name);
@@ -2545,13 +2547,6 @@ int main(int argc, char **argv)
25452547
if (files_source)
25462548
read_symbols_from_files(files_source);
25472549

2548-
/*
2549-
* When there's no vmlinux, don't print warnings about
2550-
* unresolved symbols (since there'll be too many ;)
2551-
*/
2552-
if (!have_vmlinux)
2553-
warn("Symbol info of vmlinux is missing. Unresolved symbol check will be entirely skipped.\n");
2554-
25552550
for (mod = modules; mod; mod = mod->next) {
25562551
char fname[PATH_MAX];
25572552

@@ -2595,6 +2590,10 @@ int main(int argc, char **argv)
25952590
}
25962591
}
25972592

2593+
if (nr_unresolved > MAX_UNRESOLVED_REPORTS)
2594+
warn("suppressed %u unresolved symbol warnings because there were too many)\n",
2595+
nr_unresolved - MAX_UNRESOLVED_REPORTS);
2596+
25982597
free(buf.p);
25992598

26002599
return error_occurred ? 1 : 0;

0 commit comments

Comments
 (0)